我的查詢的對象是從表a中獲取所有行,其中性別= f和用戶名不存在於表b中campid = xxxx。這裏是我成功使用查詢:MySQL加速左外部聯接/檢查空查詢
SELECT `id`
FROM pool
LEFT JOIN sent
ON pool.username = sent.username
AND sent.campid = 'YA1LGfh9'
WHERE sent.username IS NULL
AND pool.gender = 'f'
的問題是,查詢需要在9分鐘內完成,池表包含超過1000萬行,並且送出表最終要長得比更大那。我爲許多列創建了索引,包括用戶名和性別。但是,MySQL拒絕爲此查詢使用我的任何索引。我甚至嘗試使用FORCE INDEX。下面是從游泳池我的指標,並說明我的查詢的輸出:
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| pool | 0 | PRIMARY | 1 | id | A | 9326880 | NULL | NULL | | BTREE | |
| pool | 1 | username | 1 | username | A | 9326880 | NULL | NULL | | BTREE | |
| pool | 1 | source | 1 | source | A | 6 | NULL | NULL | | BTREE | |
| pool | 1 | gender | 1 | gender | A | 9 | NULL | NULL | | BTREE | |
| pool | 1 | location | 1 | location | A | 59030 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
6 rows in set (0.00 sec)
mysql> explain SELECT `id` FROM pool FORCE INDEX (username) LEFT JOIN sent ON pool.username = sent.username AND sent.campid = 'YA1LGfh9' WHERE sent.username IS NULL AND pool.gender = 'f';
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+
| 1 | SIMPLE | pool | ALL | NULL | NULL | NULL | NULL | 9326881 | Using where |
| 1 | SIMPLE | sent | ALL | NULL | NULL | NULL | NULL | 351 | Using where; Not exists |
+----+-------------+-------+------+---------------+------+---------+------+---------+-------------------------+
2 rows in set (0.00 sec)
也,這裏是我的發送表索引:
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| sent | 0 | PRIMARY | 1 | primary_key | A | 351 | NULL | NULL | | BTREE | |
| sent | 1 | username | 1 | username | A | 351 | NULL | NULL | | BTREE | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
2 rows in set (0.00 sec)
你可以看到,在不使用任何索引所以我的查詢需要很長時間。如果任何人有解決方案,涉及重新查詢,請給我一個如何使用我的數據結構的例子,以便我不會有任何混淆如何實施和測試。謝謝。
我更喜歡'(性別,用戶名,id)' –
@ypercube,好點...通過保持用戶名位於第二位置將保持該索引不會反彈到發送的表,這也將以適當的順序。我會改變它。 – DRapp
好的。我已經設置了一切符合你的規範(我認爲),但我仍然有性能問題。事實上,它現在所花費的時間比我最初使用索引時的查詢時間要長。這是我所做的:http://pastebin.com/BhyPPVqa查詢花了將近13分鐘完成。也許我做錯了什麼? – xendi