有一個警告,以我的解決方案:
1)需要說明的該解決方案是,你必須使用針對該事件表中的MyISAM引擎。如果你不能使用MyISAM,那麼這個解決方案將無法工作,因爲只有MyISAM支持空間索引。
因此,假設上面是不是你的問題,下面應該工作,給你不錯的表現:
該解決方案利用了MySQL的空間數據支持(見documentation here)。儘管可以將空間數據類型添加到各種存儲引擎,但只有MyISAM才支持Spatial R-Tree索引(請參閱documentation here),這些索引是獲得所需性能所必需的。另一個限制是空間數據類型僅適用於數字數據,因此您不能在基於字符串的範圍查詢中使用此技術。
我不會深入瞭解空間類型如何工作以及空間索引如何有用的理論細節,但您應該看看Jeremy Cole's explanation here關於如何使用空間數據類型和索引進行GeoIP查找。如果你需要原始的表現並且可以放棄一些準確性,那麼看看他們提出的一些有用的觀點和備選方案。
基本前提是我們可以採用開始/結束並使用它們中的兩個創建四個不同的點,一個用於以xy網格爲中心,以0,0爲中心的矩形的每個角,然後快速完成查找空間索引以確定我們關心的特定時間點是否在矩形內。如前所述,請參閱Jeremy Cole的解釋,以更全面地瞭解其工作原理。
在您的特定情況下,我們需要做到以下幾點:
1)改變表是一個MyISAM表(注意你不應該這樣做,除非你完全瞭解這種變化的後果比如缺少事務以及與MyISAM關聯的表鎖定行爲)。
alter table events engine = MyISAM;
2)接下來我們添加一個新的列,它將保存空間數據。我們將使用多邊形數據類型,因爲我們需要能夠保存一個完整的矩形。
alter table events add column time_poly polygon NOT NULL;
3)接下來我們填充數據的新列(請記住,該更新或插入到表事件將需要的任何進程得到修改,以確保它們也填充新列)。由於開始和結束範圍是時間,所以我們需要使用unix_timestamp函數將它們轉換爲數字(有關它的工作原理,請參閱documentation here)。
update events set time_poly := LINESTRINGFROMWKB(LINESTRING(
POINT(unix_timestamp(start_time), -1),
POINT(unix_timestamp(end_time), -1),
POINT(unix_timestamp(end_time), 1),
POINT(unix_timestamp(start_time), 1),
POINT(unix_timestamp(start_time), -1)
));
4)接下來,我們空間索引添加到表中(如前面提到的,這將只對一個MyISAM表工作,並會產生錯誤「ERROR 1464(HY000):所使用的表型不支持SPATIAL索引「)。
5)接下來,您需要使用以下select來在查詢數據時使用空間索引。
強制索引是讓100%確定MySQL將使用該索引進行查找。如果一切順利運行上述選擇解釋應該顯示類似如下的內容:
mysql> explain SELECT *
-> FROM events force index (IXs_time_poly)
-> on MBRCONTAINS(events.time_poly, POINTFROMWKB(POINT(unix_timestamp('2009-02-18 16:27:12'), 0)));
+----+-------------+-------+-------+---------------+---------------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+-------------+
| 1 | SIMPLE | B | range | IXs_time_poly | IXs_time_poly | 32 | NULL | 1 | Using where |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+-------------+
1 row in set (0.00 sec)
請參考傑里米·科爾的分析,有關此方法的性能優勢細節,該條款進行比較。
讓我知道如果您有任何問題。
感謝,
-Dipin
你的「start_time <= const以及ORDER BY start_time DESC LIMIT 1」是一個非常好的主意。由於start_date鍵似乎非常有效地使用,因此性能良好。剩下的答案應該發佈在我發佈的其他問題上! – daremon 2009-02-21 12:30:16
它也張貼在那裏:) – Quassnoi 2009-02-21 23:18:37