优化MySQL查询-多列搜索条件

Imtiaz

我正在使用MySQL 5.7.25,这是我要优化的查询:

SELECT a.contract,
       a.phone_number_1,
       a.phone_number_2,
       a.phone_number_3,
       a.phone_number_4,
       a.phone_number_5
  FROM tempdb.customer_crm a
 WHERE CHAR_LENGTH(a.contract) = 12
   AND (
         a.contract in (SELECT contract_final FROM tempdb.relevant_contracts)
         OR a.phone_number_1 in (SELECT phone_number FROM tempdb.relevant_numbers_1)
         OR a.phone_number_2 in (SELECT phone_number FROM tempdb.relevant_numbers_2)
         OR a.phone_number_3 in (SELECT phone_number FROM tempdb.relevant_numbers_3)
         OR a.phone_number_4 in (SELECT phone_number FROM tempdb.relevant_numbers_4)
         OR a.phone_number_5 in (SELECT phone_number FROM tempdb.relevant_numbers_5)
       );

customer_crm表在5列中有5个不同的电话号码。我需要筛选所有地方表的任何5个电话号码的存在记录relevant_numbers我已经表5份relevant_numbers我只能使用临时表(不能在MySQL中打开不止一次)。中的记录数:

  • customer_crm:8000万
  • related_numbers:63千
  • related_contracts:93千
  • 查询结果:10万

该查询花费的时间太长。我使用(电话号码长度条件)节省了几分钟:

SELECT a.contract,
       a.phone_number_1,
       a.phone_number_2,
       a.phone_number_3,
       a.phone_number_4,
       a.phone_number_5
  FROM tempdb.customer_crm a
 WHERE CHAR_LENGTH(a.contract) = 12
   AND (
         a.contract in (SELECT contract_final FROM tempdb.relevant_contracts)
         OR (CHAR_LENGTH(a.phone_number_1) > 9 AND a.phone_number_1 in (SELECT phone_number FROM tempdb.relevant_numbers_1))
         OR (CHAR_LENGTH(a.phone_number_2) > 9 AND a.phone_number_2 in (SELECT phone_number FROM tempdb.relevant_numbers_2))
         OR (CHAR_LENGTH(a.phone_number_3) > 9 AND a.phone_number_3 in (SELECT phone_number FROM tempdb.relevant_numbers_3))
         OR (CHAR_LENGTH(a.phone_number_4) > 9 AND a.phone_number_4 in (SELECT phone_number FROM tempdb.relevant_numbers_4))
         OR (CHAR_LENGTH(a.phone_number_5) > 9 AND a.phone_number_5 in (SELECT phone_number FROM tempdb.relevant_numbers_5))
       );

仍然需要大约10分钟。我尝试使用EXISTS条件而不是IN,它花费的时间甚至更长。我也尝试过使用左连接,这也需要更长的时间。所有列均单独索引。

任何帮助将不胜感激。谢谢。

里克·詹姆斯

OR是性能杀手。也是IN ( SELECT ... )

就目前而言,该查询将对80M行进行全表扫描,并在临时表中进行查找。如果您要为临时表建立索引,那么这些次要查询将只有1行,否则将只有63K行-总计将达到25万亿次查询。它可能在今年完成。

A计划:ORUNION

    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_contracts AS rc
            WHERE  cc.contract = rc.contract 
    )  UNION  
    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_numbers_1 AS rn
            WHERE  cc.phone_number_1 = rn.phone_number 
    )  UNION
    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_numbers_2 AS rn
            WHERE  cc.phone_number_2 = rn.phone_number 
    )  UNION
    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_numbers_3 AS rn
            WHERE  cc.phone_number_3 = rn.phone_number 
    )  UNION  
    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_numbers_4 AS rn
            WHERE  cc.phone_number_4 = rn.phone_number 
    )  UNION  
    (  SELECT  cc.id
            FROM  tempdb.customer_crm AS cc
            JOIN  tempdb.relevant_numbers_5 AS rn
            WHERE  cc.phone_number_5 = rn.phone_number 
    )

我假设idPRIMARY KEYcustomer_crm您将在以下位置使用这些索引customer_crm

INDEX(contract, id)
INDEX(phone_number_1, id)
INDEX(phone_number_2, id)
INDEX(phone_number_3, id)
INDEX(phone_number_4, id)
INDEX(phone_number_5, id)

将上面的查询用作子查询,JOIN然后返回customer_crm以获得您真正需要的任何列。

那将是大约一百万个动作-得多。

长度= 12的检查稍后可能会引起小麻烦。

方案B:不要使用5列。

通常,将事物数组分布在多个列中或打包在一起放在一个列中通常是一个糟糕的方案设计。相反,要有另一个具有(至少)两列的表:thenumber和theid联接回主表。

使用INDEX(number),具有5 * 80M行并不重要。

计划C:创建临时表之前,您是否需要备份?其他优化也是可能的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

优化MySQL搜索查询

来自分类Dev

MySQL中的搜索查询优化

来自分类Dev

MySQL中的搜索查询优化

来自分类Dev

MySQL搜索查询优化:Match ... Against与%LIKE%

来自分类Dev

优化MySQL查询以进行整数范围搜索

来自分类Dev

如何使用多列索引优化MySQL查询?

来自分类Dev

MySQL搜索多列

来自分类Dev

针对多种搜索条件优化搜索查询

来自分类Dev

具有OR条件的MySQL内部连接-查询优化

来自分类Dev

优化搜索文本的查询

来自分类Dev

MySQL搜索使用多列

来自分类Dev

搜索表的多列MySQL

来自分类Dev

MySQL搜索使用多列

来自分类Dev

通过列和WHERE子句条件的顺序同步进行MySQL查询优化

来自分类Dev

mysql group_concat重复键和1次查询中多列重复的次数(查询优化)

来自分类Dev

优化MySQL全文搜索

来自分类Dev

优化Postgres搜索查询的问题

来自分类Dev

优化子选择搜索查询

来自分类Dev

优化子选择搜索查询

来自分类Dev

在多列/多索引上优化熊猫查询

来自分类Dev

MySQL中的多列REGEX搜索

来自分类Dev

MySQL多列搜索返回错误结果

来自分类Dev

如何使用where条件的许多组合来优化MySQL查询?

来自分类Dev

MYSQL查询优化-如何从连接的右表中获取唯一列

来自分类Dev

如何优化此MySQL查询以仅返回选定的列并选择其顺序?

来自分类Dev

当列包含重复值时如何使用索引优化MySQL查询

来自分类Dev

PHP mysql多词搜索查询

来自分类Dev

MySQL查询多列排序

来自分类Dev

MySQL查询返回多列