Mysql 可能有太多索引
我在我的應用程序中使用 php 框架 Laravel 以及 mysql 5.6,以便使用 innoBD 進行全文搜尋。
但我不確定我是否有太多索引。
我的應用程序允許使用者上傳產品進行銷售。所以查詢最多的表 Select / inserts 就是我的 products 表。
表看起來像這樣,(在此範例中刪除了幾行)。
產品
p_id - (int) Primary key
用於過濾產品,新/舊 - asc/desc
state_id - (int) index key & foreign key
連結到狀態表中的主鍵以獲取狀態名稱,也用於搜尋產品時的過濾
city_id - (int) index key & foreign key
城市表中的主鍵連結,以獲取城市名稱,也用於搜尋產品時的過濾
cat_id - (int) index key & foreign key
連結到類別表中的主鍵以獲取類別名稱,也用於搜尋產品時的過濾
subcat_id - (int) index key & foreign key
連結到子類別表中的主鍵以獲取子類別名稱,也用於搜尋產品時的過濾
title - (varchar) FULLTEXT search
用於文本搜尋,搜尋/過濾產品時
seller_id - (int) index key & foreign key
連結到使用者表中的主鍵以獲取賣家使用者名
product_type - (tinyint) index key
如果產品是廣告或拍賣,則在搜尋/過濾產品時使用
price - (int) index key
搜尋/過濾產品時使用
end_time - timestamp
is_active - (tinyint) index key
搜尋/過濾產品時使用因此,在搜尋產品時,總共會有 4 個
inner joins
,我沒有在搜尋結果中顯示賣家名稱。只有內部連接,州/城市/類別/子類別。至於現在我總共有 8 個索引鍵和 5 個外鍵。
**我的第一個問題:**我是否需要在所有具有外鍵的列上放置一個索引鍵?
我也在考慮添加幾個複合索引。
複合索引 1:(title、state_id、city_id、cat_id、subcat_id、product_type、is_active)
複合索引 2:(title、state_id、city_id、product_type、is_active)
就目前而言,大多數使用者似乎只進行文本搜尋。所以最常見的查詢是全文搜尋,其中 is_active = 1
與其嘗試猜測,不如下載 Percona Tools。
您應該使用工具pt-duplicate-key-checker。它將為您比較所有索引,並為您提供 ALTER TABLE 命令以刪除您不需要的索引,並且仍然完全符合您的所有索引搜尋需求。這是執行此操作的程式碼:
ETL_INDX_SCRIPT=/tmp/remove_indexes.sql MYSQL_USER=root MYSQL_PASS=rootpassword MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}" DB=mydb pt-duplicate-key-checker ${MYSQL_CONN} -d ${DB} | grep "^ALTER TABLE " >> ${ETL_INDX_SCRIPT} mysql ${MYSQL_CONN} -AN 2>/dev/null < ${ETL_INDX_SCRIPT}
如果不確定,請先查看索引刪除 SQL 腳本的內容
ETL_INDX_SCRIPT=/tmp/remove_indexes.sql MYSQL_USER=root MYSQL_PASS=rootpassword MYSQL_CONN="-u${MYSQL_USER} -p${MYSQL_PASS}" DB=mydb pt-duplicate-key-checker ${MYSQL_CONN} -d ${DB} | grep "^ALTER TABLE " >> ${ETL_INDX_SCRIPT} vi -R ${ETL_INDX_SCRIPT}
如果生成的腳本沒有 ALTER TABLE 命令,則無需執行任何操作。
如果有 ALTER TABLE 命令並且您已準備好,請使用此命令執行腳本
mysql ${MYSQL_CONN} -AN 2>/dev/null < ${ETL_INDX_SCRIPT}
試一試 !!!