[英]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 < value
或variable > value
或variable 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.