繁体   English   中英

通过查询订购要花费太多时间

[英]Order by query is taking too much time

我有80k多客户,有4个群组。 现在,我想在mysql中通过查询找到2个组用户。 我的查询如下:

select c.customers_firstname as recipient_firstname, 
       c.customers_lastname as  recipient_lastname,
       c.customers_id as recipient_id, 
       c.customers_email_address as recipient_email_address 
from customers c
where customers_group_id = '1' OR customers_group_id = '3'

当我在phpmyadmin中运行此查询时,得到的结果是: 显示第0-29行(总共59,815行,查询耗时0.0034秒)

但是,当我在此查询中按ORDER BY recipient_firstname ASC receiver_firstname ORDER BY recipient_firstname ASC添加订单时,结果时间为: 显示第0-29行(总计59,815行,查询耗时0.2607秒)

查询订单花费太多时间来获得结果。

我想减少查询的订购时间。

如果有其他方法可以在更短的时间内获得相同的结果,请提供帮助。

您需要在recipient_firstname字段上建立索引(因此,确实是customer.customers_firstname)。 索引允许对结果集进行有序的线性时间迭代。

如果没有索引,则必须先对结果集进行汇总,然后再进行排序。 该排序将为n log n 对于大型集来说,这显然很慢,而且如果它不能容纳到内存中(并且60k记录可能不取决于配置),它将进行非常慢的基于文件的排序。

tl; dr您需要一个索引。 recipient_firstname上的索引将使查询的性能与非ORDER BY版本极为接近。


顺便说一句,如果customers_group_id是整数字段,请使用整数文字而不是字符串。 它可能不会有所作为,但会产生误导,实际上在某些情况下它很重要。


根据情况,可能还值得在组ID上添加索引。 对于小型集,结果可以在构建集时进行过滤,但是对于大型结果集,最终将需要大量磁盘全表扫描。

您必须在customers_firstname字段上建立索引:这将加快ORDER BY速度, 但同时也会减慢WHERE速度 (现在可能已建立索引)。

因此,该索引必须按此顺序为customers_group_id, customers_firstname

CREATE INDEX my_query_ndx 
    ON customers ( customers_group_id, customers_firstname );

理论上,您可以将索引扩大为覆盖索引,并在两个关键字段之后包含SELECT需要的所有其他字段。 但是,维护此类索引非常昂贵。 您必须权衡利弊。 如果表非常“宽”,则在组ID,名字,姓氏,ID和电子邮件上建立索引可能是有利的。

小(或不太小)查询改进

where customers_group_id = '1' OR customers_group_id = '3'

为了清楚起见,可以将其重写为(不变)

WHERE customers_group_id IN ('1','3')

但是现在, customer_group_id是一个整数字段,或者不是。 如果是这样,那么最好这样对待:

WHERE customers_group_id IN (1, 3)

在某些情况下,您可以预先计划ID,例如,第3组实际上是第2组,即您可能感兴趣的组是连续的。 这样,您可以将查询重写为variable < valuevariable > valuevariable BETWEEN ,其速度是OR两倍。 使用大型OR集,您可以轻松获得4倍的加速比。

如果它不是整数字段,则一定要使其成为一个整数字段。 整数性能(和索引大小)将大大受益(但是,请注意,对于字符串,“ 3”大于“ 12”,就像“ C”大于“ AB”一样;因此,类型转换不一定没有边)效果)。

尝试创建索引(customers_group_id, customers_firstname) -这应该可以工作。

您需要在应用了order by子句的列上创建索引

CREATE INDEX index_name ON customers (customers_firstname);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM