Mysql
為什麼 MySQL 在查詢中忽略我的索引?
我在生產數據庫伺服器(主伺服器)中有以下查詢:
SELECT * FROM Enlace_llamadas where id_empresa IN (1,5,33,36,40,44,48,53,55,111,115,125,127,151,167,175,181,185,187,189,195,199,201,203,207,209,221,223,231,233,239,241,243,244,247,249,251,253,257,259,261,276,277,281,283,287,291,293,301,305,307,313,315,319,323,339,341,343,345,359,367,371,379,381,383,385,387,391,393,395,397,421,423,425,429,431,433,437,439,441,445,447,451,454,463,469,477,479,481,489,491,495,497,501,507,510,514,520,522) AND date(fecha_inicio)=date(NOW()) and Enlace_llamadas.fecha_fin='0000-00-00 00:00:00' and TIMESTAMPDIFF(MINUTE,fecha_inicio, NOW()) >= '5';
在此伺服器中執行 EXPLAIN,結果如下:
+----+-------------+-----------------+------+------------------------------------------------------------------------+------+---------+------+----------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-----------------+------+------------------------------------------------------------------------+------+---------+------+----------+-------------+ | 1 | SIMPLE | Enlace_llamadas | ALL | id_empresa_id_agente,idx_empresa_campana,id_empresa_cliente,id_empresa | NULL | NULL | NULL | 41330453 | Using where | +----+-------------+-----------------+------+------------------------
此查詢需要很長時間,執行時間將近 40 秒,並且機器資源使用大量 CPU 超過 0f 500%。執行
SHOW INDEX FROM nombre_tabla
,這是結果表。| Enlace_llamadas | 0 | PRIMARY | 1 | id | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_campana | 1 | id_campana | A | 19700 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_cliente | 1 | id_cliente | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_numero_cliente | 1 | id_numero_cliente | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_id_agente | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_id_agente | 2 | id_agente | A | 19468 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | idx_empresa_campana | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | idx_empresa_campana | 2 | id_campana | A | 19569 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_cliente | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_cliente | 2 | id_cliente | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | i_Enlace_llamadas_fechas | 1 | fecha_inicio | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | i_Enlace_llamadas_fechas | 2 | fecha_fin | A | 41330863 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_agente | 1 | id_agente | A | 8516 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | +-----------------+------------+--------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 14 rows in set (0.00 sec)
另一個伺服器(從屬伺服器)中的相同查詢需要 0.21 秒。這是從伺服器中的執行計劃。
id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-----------------+------+-------------------------------------------------------------------------------------------------+--------------------------+---------+-------+------+------------------------------------+ | 1 | SIMPLE | Enlace_llamadas | ref | id_empresa,i_Enlace_llamadas_fechas,id_empresa_id_agente,id_empresa_cliente,idx_empresa_campana | i_Enlace_llamadas_fechas | 8 | const | 276 | Using index condition; Using where
此伺服器上此表的索引
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | +-----------------+------------+--------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ | Enlace_llamadas | 0 | PRIMARY | 1 | id | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_campana | 1 | id_campana | A | 78826 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_cliente | 1 | id_cliente | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_numero_cliente | 1 | id_numero_cliente | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_agente | 1 | id_agente | A | 9389 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | i_Enlace_llamadas_fechas | 1 | fecha_fin | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | i_Enlace_llamadas_fechas | 2 | fecha_inicio | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_id_agente | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_id_agente | 2 | id_agente | A | 42663 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_cliente | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | id_empresa_cliente | 2 | id_cliente | A | 46034401 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | idx_empresa_campana | 1 | id_empresa | A | 18 | NULL | NULL | | BTREE | | | | Enlace_llamadas | 1 | idx_empresa_campana | 2 | id_campana | A | 22271 | NULL | NULL | | BTREE | | | +-----------------+------------+--------------------------+--------------+-------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+ 14 rows in set (0.00 sec)
這是什麼原因?
正確格式化輸出後,您可以看到
i_Enlace_llamadas_fechas
兩個伺服器之間的定義不同——第二個伺服器中的列順序顛倒了,這使得它適合那裡的查詢。
如果您需要對它們進行索引,請不要隱藏函式中的列。
AND date(fecha_inicio)=date(NOW())
如果
fecha_inicio
是類型DATE
,只需執行AND fecha_inicio = CURDATE()
如果是
DATETIME
,那麼做AND fecha_inicio >= CURDATE() AND fecha_inicio < CURDATE() + INTERVAL 1 DAY
這是在做什麼?
and TIMESTAMPDIFF(MINUTE,fecha_inicio, NOW()) >= '5';
如果它正在檢查它是否在最後 5 分鐘內,只需執行
AND fecha_inicio > NOW() - INTERVAL 5 MINUTE
並擺脫日期測試(除非跨越午夜有什麼特別之處)。
然後有這個複合索引:
INDEX(fecha_fin, id_empresa, fecha_inicio) -- in this order
如果您需要進一步討論,請提供
SHOW CREATE TABLE MySQL version Size of tables