2017-05-30 88 views
0

我有一個怪異的情況正在進行。我的一個夜間查詢,通常需要5分鐘,耗時> 12小時。下面是該查詢:MySql - Innodb - 腐敗索引/外鍵

SELECT Z.id, 
     Z.seoAlias, 
     GROUP_CONCAT(DISTINCT LOWER(A.include)) AS include, 
     GROUP_CONCAT(DISTINCT LOWER(A.exclude)) AS exclude 
FROM df_productsbystore   AS X 
INNER JOIN df_product_variants AS Y ON Y.id = X.id_variant 
INNER JOIN df_products   AS Z ON Z.id = Y.id_product 
INNER JOIN df_advertisers  AS A ON A.id = X.id_store 
WHERE X.isActive > 0 
AND Z.id > 60301433 
GROUP BY Z.id 
ORDER BY Z.id 
LIMIT 45000; 

我跑的解釋並得到如下:

+----+-------------+-------+--------+------------------------------------------------------------------------------------+-----------+---------+---------------------+------+---------------------------------+ 
| id | select_type | table | type | possible_keys                  | key  | key_len | ref     | rows | Extra       | 
+----+-------------+-------+--------+------------------------------------------------------------------------------------+-----------+---------+---------------------+------+---------------------------------+ 
| 1 | SIMPLE  | A  | ALL | PRIMARY                   | NULL  | NULL | NULL    | 365 | Using temporary; Using filesort | 
| 1 | SIMPLE  | X  | ref | UNIQUE_variantAndStore,idx_isActive,idx_store          | idx_store | 4  | foenix.A.id   | 600 | Using where      | 
| 1 | SIMPLE  | Y  | eq_ref | PRIMARY,UNIQUE,idx_prod               | PRIMARY | 4  | foenix.X.id_variant | 1 | Using where      | 
| 1 | SIMPLE  | Z  | eq_ref | PRIMARY,UNIQUE_prods_seoAlias,idx_brand,idx_gender2,fk_df_products_id_category_idx | PRIMARY | 4  | foenix.Y.id_product | 1 | NULL       | 
+----+-------------+-------+--------+------------------------------------------------------------------------------------+-----------+---------+---------------------+------+---------------------------------+ 

哪個看着我的開發環境不同。該df_advertisers部分看起來腥我,所以我刪除並重新創建的X.id_store列的索引,而現在的EXPLAIN這個樣子的,查詢快捷又是:

+----+-------------+-------+--------+------------------------------------------------------------------------------------+------------------------+---------+-------------------+---------+-------------+ 
| id | select_type | table | type | possible_keys                  | key     | key_len | ref    | rows | Extra  | 
+----+-------------+-------+--------+------------------------------------------------------------------------------------+------------------------+---------+-------------------+---------+-------------+ 
| 1 | SIMPLE  | Z  | range | PRIMARY,UNIQUE_prods_seoAlias,idx_brand,idx_gender2,fk_df_products_id_category_idx | PRIMARY    | 4  | NULL    | 2090691 | Using where | 
| 1 | SIMPLE  | Y  | ref | PRIMARY,UNIQUE,idx_prod               | UNIQUE     | 4  | foenix.Z.id  |  1 | Using index | 
| 1 | SIMPLE  | X  | ref | UNIQUE_variantAndStore,idx_isActive,idx_id_store         | UNIQUE_variantAndStore | 4  | foenix.Y.id  |  1 | Using where | 
| 1 | SIMPLE  | A  | eq_ref | PRIMARY                   | PRIMARY    | 4  | foenix.X.id_store |  1 | NULL  | 
+----+-------------+-------+--------+------------------------------------------------------------------------------------+------------------------+---------+-------------------+---------+-------------+ 

這樣看來,該指數奇蹟般地消失了。任何人都可以解釋這是可能的嗎?我的意思是定期運行mysqlcheck命令或類似命令以避免這種情況?我很難過!

感謝

回答

1

下一次,簡單地做ANALYZE TABLE df_productsbystore;這將是非常快的,並且可以解決問題。

ANALYZE重新計算優化程序所依據的統計信息,以決定在此情況下決定使用哪個表。在極少數情況下,統計數據會過時並需要在小腿上踢球。

警告:我假設你在最近的版本上使用InnoDB。如果您使用的是MyISAM,則更經常需要ANALYZE

你真的需要45K行嗎?你會怎麼做這麼多?

的一種方式,以加快查詢了(可能)是做,一切可以用X和Z子查詢然後JOIN A做休息:

SELECT XYZ.id, XYZ.seoAlias, 
     GROUP_CONCAT(DISTINCT LOWER(A.include)) AS include, 
     GROUP_CONCAT(DISTINCT LOWER(A.exclude)) AS exclude 
    FROM 
    (
     SELECT Z.id, Z.seoAlias, X.id_store 
      FROM df_productsbystore AS X 
      INNER JOIN df_product_variants AS Y ON Y.id = X.id_variant 
      INNER JOIN df_products AS Z   ON Z.id = Y.id_product 
      WHERE X.isActive > 0 
       AND Z.id > 60301433 
      GROUP BY Z.id -- may not be necessary ?? 
      ORDER BY Z.id 
      LIMIT 45000 
    ) AS XYZ 
    INNER JOIN df_advertisers AS A ON A.id = XYZ.id_store 
    GROUP BY ZYZ.id 
    ORDER BY XYZ.id; 

有用的指標:

Y: INDEX(id_product, id) 
X: INDEX(id_variant, isActive, id_store) 
+0

嗨裏克,感謝您的職位。 ANALYZE似乎沒有工作,我認爲我們的數據庫是搞砸了: – mils

+0

重新配置的查詢,再加上索引沒有區別嗎? –

+0

嗨瑞克,你重新配置的查詢是非常好的。當機器快速運行時,差異很小但隨後機器運行速度變慢,查詢速度明顯加快,我所能想到的只是它與緩存有關,再次感謝。 – mils

0

爲了解決這個問題,我嘗試刪除並重新創建索引+ FK。這並不是第一次解決問題,而是機器處於負載狀態,但它在安靜的機器上第二次工作。

它只是感覺像MySQL是片狀。我真的不知道還有什麼要說的。

感謝您的幫助,雖然