2015-10-19 26 views
0

我看到,運行ANALYZE導致性能顯着差我在兩張表之間做的特定JOIN更糟糕的查詢計劃與加入後ANALYZE

假設以下模式:

CREATE TABLE a (id INTEGER PRIMARY KEY, name TEXT); 
CREATE TABLE b (a NOT NULL REFERENCES a, value INTEGER, PRIMARY KEY(a, b)); 

CREATE VIEW ab AS SELECT a.name, b.text, MAX(b.value) 
FROM a 
JOIN b ON b.a = a.id; 
GROUP BY a.id 
ORDER BY a.name 

表a是大約10K行,表b約爲48K行(〜每行5行表A)。

之前ANALYZE

現在,當我運行以下查詢:

SELECT * FROM ab; 

查詢計劃如下所示:

1|0|0|SCAN TABLE b 
1|1|1|SEARCH TABLE a USING INTEGER PRIMARY KEY (rowid=?) 

這是一個很好的計劃,b爲大我希望它在外部循環中,利用表格a中的索引。它在一秒鐘內完成。

當我再次執行相同的查詢後ANALYZE

,查詢計劃產生兩個表掃描:

1|0|1|SCAN TABLE a 
1|1|0|SCAN TABLE b 

這是迄今爲止最佳。由於某種原因,查詢規劃者認爲10K行的外部循環和48K行的內部循環更適合。這需要大約1.5分鐘才能完成。

我是否應該調整表b中的索引以使其在ANALYZE之後工作?還有什麼可以改變爲索引/模式?

我只是試着在這裏理解這個問題。我使用CROSS JOIN解決了這個問題,但這感覺很髒,我不明白爲什麼規劃者會採用比未分析計劃慢幾個數量級的計劃。它似乎與GROUP BY有關,因爲查詢規劃器將表b放在沒有它的外部循環中(但它使得查詢對於我想要的無用)。

回答

0

意外地通過調整視圖定義中的GROUP BY子句找到答案。取而代之的是加入a.id,我改爲b.a,儘管它們具有相同的值。

CREATE VIEW ab AS SELECT a.name, b.text, MAX(b.value) 
FROM a 
JOIN b ON b.a = a.id; 
GROUP BY b.a   -- <== changed this from a.id to b.a 
ORDER BY a.name 

我仍然不完全確定它們之間有什麼不同,因爲它將相同的數據進行分組。