Mysql

Mysql 可能有太多索引

  • February 10, 2015

我在我的應用程序中使用 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}

試一試 !!!

引用自:https://dba.stackexchange.com/questions/87450