我有80多个客户,有4个小组。现在我想找到2组用户在mysql中查询。我的查询如下:
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
添加订单时,结果时间为:显示0到29行(总计59,815,查询花费0.2607秒)
按查询的顺序对结果花费了太多时间。
我希望通过查询减少订单的时间。
如果有其他方法可以在更短的时间内获得相同的结果,请提供帮助。
答案 0 :(得分:3)
您需要recipient_firstname
字段的索引(所以确实是customers.customers_firstname)。索引允许对结果集进行有序的线性时间迭代。
如果您没有索引,则必须聚合结果集然后进行排序。这种排序将是n log n
。对于大型集合而言,这显然相当慢,如果它无法适应内存(并且60k记录可能不依赖于配置),那么它将基于文件进行非常慢的排序。
tl; dr 您需要一个索引。 recipient_firstname
上的索引会使查询在性能上与非ORDER BY
版本非常接近。
顺便说一下,如果customers_group_id是一个整数字段,请使用整数文字,而不是字符串。它可能不会有所作为,但它会产生误导,实际上有一些情况很重要。
根据具体情况,可能还需要在组ID上添加索引。对于小集合,结果可以在构建集合时进行过滤,但对于大型结果集,最终需要进行相当大量的全表扫描。
答案 1 :(得分:3)
您必须在customers_firstname
字段上编制索引:这会加快ORDER BY
,,但也会减慢WHERE
(可能会被编入索引)现在)。
因此索引必须按此顺序为customers_group_id, customers_firstname
。
CREATE INDEX my_query_ndx
ON customers ( customers_group_id, customers_firstname );
理论上,您可以将索引放大为覆盖索引,并在两个关键字段之后包含SELECT
中所需的所有其他字段。但是,保持这种指数是昂贵的;你必须平衡优点和缺点。如果表格非常“宽”,那么对组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 < value
或variable > value
或variable BETWEEN
,其速度是OR
的两倍。使用大OR
个集合,您可以轻松获得4倍的加速。
如果它不是整数字段,那么一定要努力使它成为一个整数字段。整数性能(和索引大小)将受益匪浅(但请注意,对于字符串,'3'大于'12',正如'C'大于'AB';因此,类型转换不一定没有边效果)。
答案 2 :(得分:1)
尝试创建索引(customers_group_id, customers_firstname)
- 这应该可行。
答案 3 :(得分:0)
您需要create index关于应用order by子句的列。
CREATE INDEX index_name ON customers (customers_firstname);