這更像是一個通用的SQL問題,但如果有人知道Firebird/Interbase特定優化,我會使用Firebird 2.5。首先,下面是一個簡單的例子架構來說明我試圖解決這一問題:在對外鍵進行排序時加速SQL查詢
CREATE TABLE users
(
id INTEGER PRIMARY KEY,
name VARCHAR(16)
);
CREATE TABLE data_set
(
id INTEGER PRIMARY KEY,
name VARCHAR(64)
);
CREATE UNIQUE INDEX data_set_name_idx ON data_set(name);
CREATE TABLE data
(
user_id INTEGER,
data_set_id INTEGER,
data BLOB,
PRIMARY KEY(user_id, data_set_id)
);
CREATE INDEX data_user_id_idx ON data(user_id);
CREATE INDEX data_data_set_id_idx ON data(data_set_id);
我試圖運行查詢如下:
SELECT users.name, data_set.name, data FROM users, data_set, data
WHERE user_id=XXX AND user_id=users.id AND data_set_id=data_set.id
ORDER BY data_set.name;
隨着「XXX」正在填寫user_id我想要的。所以我正在做的是從數據表中選擇屬於特定用戶的所有行,並且我正在根據data_set名稱對結果進行排序。
這工作,因爲它是,但問題是數據表有超過十億行中它和data_set表不小任。單個用戶ID的結果集可能有數十億行。會發生什麼情況是,爲了使ORDER BY工作數據庫必須創建大量的臨時數據,這些數據非常慢,並且使用大量磁盤空間。如果沒有ORDER BY,它很快,但顯然不會按照我的需要排序。
一個解決辦法是採取data_set.name值,只是把它們放在一個VARCHAR列在數據。然後可以編制索引並快速排序。這種方法的問題是它會有很多重複的數據,並使數據庫變得非常龐大。
另一種解決方案將類似於索引視圖或索引計算列。據我所知,Firebird都不支持這些功能。
還有其他想法嗎?
我沒有確定的答案,但我認爲你可以更多地使用索引來玩,並用查詢來對它們進行基準測試。 – 2009-11-03 12:14:01
爲什麼要首先爲單個用戶提供「數億行」?不僅需要處理查詢而且需要將數據傳輸到客戶端。 – liggett78 2009-11-03 14:35:05
@ liggett78:哦,我同意它將需要時間來傳輸它,因爲它有很多數據。這就是爲什麼我想盡可能地加快速度。它不需要像現在這樣慢,因爲它浪費了大量時間爲這種排序創建臨時數據。 – 2009-11-03 16:06:21