Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不使用索引的Mysql查询_Mysql_Sql - Fatal编程技术网

不使用索引的Mysql查询

不使用索引的Mysql查询,mysql,sql,Mysql,Sql,我在mysql中有一个相当大的订单表(大约120k行,并且还在增长),我在mysql慢速日志中看到一些查询花费的时间太长。 由于这个原因,我在服务器上也有一些峰值负载 其中一个问题是: SELECT [list of fields] FROM orders o LEFT JOIN orders_total ot ON ( o.orders_id = ot.orders_id ) LEFT JOIN orders_status s

我在mysql中有一个相当大的订单表(大约120k行,并且还在增长),我在mysql慢速日志中看到一些查询花费的时间太长。 由于这个原因,我在服务器上也有一些峰值负载

其中一个问题是:

SELECT [list of fields] 
FROM   orders o 
       LEFT JOIN orders_total ot 
              ON ( o.orders_id = ot.orders_id ) 
       LEFT JOIN orders_status s 
              ON o.orders_status = s.orders_status_id 
WHERE  s.language_id = '3' 
       AND ot.class = 'ot_total' 
       AND ( o.customers_name LIKE '%126627%' 
              OR o.customers_company LIKE '%126627%' 
              OR o.orders_id LIKE '%126627%' 
              OR o.delivery_name LIKE '%126627%' 
              OR o.delivery_company LIKE '%126627%' 
              OR o.customers_email_address LIKE '%126627%' 
              OR o.customers_telephone LIKE '%126627%' 
              OR o.billing_name LIKE '%126627%' 
              OR o.billing_company LIKE '%126627%' 
              OR o.billing_nif LIKE '%126627%' ) 
ORDER  BY o.orders_id DESC 
LIMIT  0, 20; 
对这些问题进行了解释,并得出以下结论:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  o   index   PRIMARY,order_status    PRIMARY 4   NULL    127733  Using where
1   SIMPLE  s   eq_ref  PRIMARY PRIMARY 8   o.orders_status,const   1   Using where
1   SIMPLE  ot  ref idx_orders_total_orders_id  idx_orders_total_orders_id  4   o.orders_id 4   Using where
如您所见,查询正在遍历表订单的所有记录

表订单的状态为
orders\u
index

如何避免这种情况? 它是一个
MyISAM
表,将它变成
InnoDB
将解决这个峰值负载问题


谢谢

这可能无法修复您的查询,但是
左连接
s应该是内部的
连接
s。无论如何,
where
子句将它们转换为内部联接

请参阅此版本查询的解释:

SELECT [list of fields] 
FROM orders o JOIN
     orders_total ot 
     ONo.orders_id = ot.orders_id JOIN
     orders_status s 
     ON o.orders_status = s.orders_status_id 
WHERE s.language_id = '3' AND ot.class = 'ot_total' AND
      (o.customers_name LIKE '%126627%' OR
       o.customers_company LIKE '%126627%' OR
       o.orders_id LIKE '%126627%' OR
       o.delivery_name LIKE '%126627%' OR
       o.delivery_company LIKE '%126627%' OR
       o.customers_email_address LIKE '%126627%' OR
       o.customers_telephone LIKE '%126627%' OR
       o.billing_name LIKE '%126627%' OR
       o.billing_company LIKE '%126627%' OR
       o.billing_nif LIKE '%126627%'
      ) 
ORDER BY o.orders_id DESC 
LIMIT 0, 20; 
注意:还要检查
s.language_id
是字符串还是数字。如果是数字,请删除单引号。有时这些会影响优化

假设您有正确的索引(例如
orders(orders\u id,status\u id)
orders\u total(class,order\u id)
order\u status(order\u id)
),仍有几种方法可以运行查询

因为除了扩展的
like
子句之外还有其他条件,所以查询不必进行完整的表扫描。然而,一个大问题是,其他两个条件(阶级和地位)的选择性如何。我的猜测是,这些都不是很有选择性的——也就是说,超过1%的行符合这些条件。优化器决定扫描表是解决此查询的最有效方法


顺便说一下,类似于的情况看起来非常可疑。如果您正在字符字段中查找单词,则可以考虑全文搜索,这要快得多。

字符串在该查询“代码>”中搜索…像“%126627%”这样的行是不可搜索的,因此如果有许多行与其他条件匹配,将导致糟糕的性能。您可能想考虑使用FultLeXT索引,或者像SoR或狮身人面像这样的搜索引擎。当左联接时,WHERE子句中的右表条件使外部联接工作作为内部连接,即将“S.LoalGracyID=3”改为ON子句,并且还移动“OT.Cype=OTyToTo”。(如果需要外部联接…!)所有条件列名称(如“%pattern%”)都使用完全扫描。如果您想提供帮助,您需要向我们展示一些附加信息,如表定义和实际sql查询的示例。正如jarlh所说,orders\u状态的外部连接,那么根据s.language\u id进行过滤是很奇怪的。订单数量和类别相同。这些左连接应该是内部连接,或者语言id和类条件应该是外部连接条件的一部分。解决方案实际上是规范化数据库,并创建另一个表,将WHERE子句中的模式中的所有id与orders表中的特定记录连接起来。