我有一個存儲要爬網的URI列表的表。這種 'crawl_index' 表架構是:MySQL - 「由...分組」的性能問題
CREATE TABLE `crawl_index` (
`id` INTEGER(10) NOT NULL AUTO_INCREMENT,
`uri` TEXT NOT NULL,
`domain` VARCHAR(255) NOT NULL,
`last_crawled_date` INTEGER(10) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
INDEX `crawler_INDEX_1` (`domain`),
INDEX `crawler_INDEX_2` (`last_crawled_date`)
) ENGINE=InnoDB;
這個表的一些細節:
- 它包含了1M行。
- 將近60%的行將「last_crawled_date」設置爲0(從爬網頁面提取URI比從實際爬行頁面更快)。
- 從不使用「id」字段。我只是將它添加到模式中以具有明確的primary_key,因爲我無法在「uri」字段上創建主鍵,因爲它是未綁定的文本。
我想要做的是有以下限制來選擇N行:
- 的URI不應該是已經在最後2天爬
- 我不希望所有返回URI來自同一個域,以避免同時在同一個域上執行太多的請求。
就目前而言,我想這個查詢:
select * from crawl_index where last_crawled_date <= 1373273029 group by domain limit 3;
它給了我這樣的結果:
+--------+------------------------+--------------+-------------------+
| id | uri | domain | last_crawled_date |
+--------+------------------------+--------------+-------------------+
| 60239 | http://example1.com/1 | example1.com | 0 |
| 239 | http://example2.com/1 | example2.com | 0 |
| 120239 | http://example3.com/1 | example3.com | 0 |
+--------+------------------------+--------------+-------------------+
3 rows in set (1,23 sec)
它的工作原理,但與沒有相同的查詢是很慢「小組通過」聲明。當我在該查詢運行explain
,我得到這個:
+----+-------------+-------------+-------+-----------------+-----------------+---------+------+-------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------------+-------+-----------------+-----------------+---------+------+------+------------------------+
| 1 | SIMPLE | crawl_index | range | crawler_INDEX_1 | crawler_INDEX_2 | 4 | NULL | 71588 | Using index condition |
| | | | | crawler_INDEX_2 | | | | | Using temporary |
| | | | | | | | | | Using filesort |
+----+-------------+-------------+-------+-----------------+-----------------+---------+------+-------+-----------------------+
我已經:
- 創建LAST_CRAWLED_DATE和域名領域指標
- 使用整數來存儲我LAST_CRAWLED_DATE避免日期時間比較
- 預先計算我的PHP代碼中的max_date,以避免讓mysql爲我做這件事。
我可以改進這個查詢的任何想法?
使用'ENUM'似乎不可能,因爲每次我們想要添加新的域進行爬網時,它都會需要更新模式。增加內存限制是個好主意。我會測試它,並會告訴你它是否增加了性能。但現在,我試圖理解爲什麼突然解釋告訴我,它不再使用「filesort」,「臨時」和「索引」了,而只是「在哪裏」......只有改變我做的是添加一個我桌上有幾十萬個uris來模擬生產約束。響應時間基本相同:1.5到2次之間。奇怪... – Remi