2014-03-01 93 views
1

看起來使用order by + limit的確很慢,使用order by有點慢,而使用just limit是相當快的。這些查詢的解釋都使用filesort。類似的是'%search%'兩端狂放,所以我知道它不能使用索引。mysql order by + limit slows query down

我不明白爲什麼通過限制的訂單比僅僅通過訂單慢得多。

如果我有下面的查詢,大約需要250毫秒:(在同一格式中有多個類似的查詢)。這使用AND限制的順序。 (最慢)

$this->db->select('category'); 
$this->db->from('items'); 
$this->db->where('deleted',0); 
$this->db->distinct(); 
$this->db->like('category', $search); 
$this->db->order_by("category", "asc"); 
$this->db->limit($limit); 

如果我有下面的查詢大約需要65毫秒毫秒(有多個相同的格式類似的查詢)。這僅使用LIMIT(最快)

$this->db->select('category'); 
$this->db->from('items'); 
$this->db->where('deleted',0); 
$this->db->distinct(); 
$this->db->like('category', $search); 
$this->db->limit($limit); 

如果我有後續的查詢需要花費大約75ms毫秒(有相同的格式多個類似的查詢)

$this->db->select('category'); 
$this->db->from('items'); 
$this->db->where('deleted',0); 
$this->db->distinct(); 
$this->db->like('category', $search); 
$this->db->order_by("category", "asc"); 
+2

'Order by'需要對整個結果集進行排序。這需要時間。 'limit'只是在SQL引擎遇到它們時返回行。 –

+0

您可以嘗試添加索引覆蓋列(刪除,類別),或者只是索引覆蓋列類別。 – Juho

+0

您可能希望爲「類別」列編制索引,以改進使用「按類別排序」的查詢。 –

回答

0
$this->db->select('category'); 
$this->db->from('items'); 
$this->db->where('deleted',0); 
$this->db->distinct(); 
$this->db->like('category', $search); 
$this->db->limit($limit); 

該查詢的工作這樣:

  1. MySQL掃描表items使用索引或使用序列掃描。

  2. 當類別符合條件category LIKE $search時,MySQL將此記錄返回給您。

  3. 當$ limit達到時,MySQL停止執行。這很快。 (我認爲$limit是沒有那麼大在您的測試)

但隨着ORDER BY查詢其他方式執行:

$this->db->select('category'); 
$this->db->from('items'); 
$this->db->where('deleted',0); 
$this->db->distinct(); 
$this->db->like('category', $search); 
$this->db->order_by("category", "asc"); 
$this->db->limit($limit); 
  1. MySQL的搜索表items使用索引或使用序列搜索到桌子的盡頭。

  2. 當類別條件category LIKE $search,MySQL的店這個記錄的地方(臨時文件或內存緩存)

  3. MySQL的排序中的臨時文件或內存緩存中的所有記錄匹配

  4. 使用順序掃描讀取$極限來自緩存的記錄並將它們返回給您。

在第一個查詢中,MySQL會執行最小$ limit的比較。在第二個查詢中,MySQL與表中的記錄做比較,然後排序(我假設)一個大記錄集。

UPD對不起,這不是你的問題的答案。

將所有這些查詢寫入文本文件(不要使用框架)並測試它們並查看EXPLAIN。 也許MySQL在添加'LIMIT'時改變策略

+0

他的問題是,爲什麼查詢在限制和order by方面比只使用order by要慢。直覺表明,使用限制會加快查詢速度,因爲返回行所需的I/O較少。 – poroszd