表words
包含word
和id
列以及50000条记录。我知道结构%XC%A
的字词位于id=30000
和id=35000
之间。
现在考虑以下问题:
SELECT * FROM words WHERE word LIKE '%XCX%A'
和
SELECT * FROM words WHERE id>30000 and id < 35000 and word LIKE '%XCX%A'
从耗时的角度来看,它们之间有什么区别吗?
答案 0 :(得分:2)
好吧,让我们找出......
这是一个大约50000字的数据集。一些单词(但仅在30000到35000范围内)遵循所描述的模式:
EXPLAIN
SELECT * FROM words WHERE word LIKE '%XCX%A';
+----+-------------+-------+-------+---------------+------+---------+------+-------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+------+---------+------+-------+--------------------------+
| 1 | SIMPLE | words | index | NULL | word | 14 | NULL | 50976 | Using where; Using index |
+----+-------------+-------+-------+---------------+------+---------+------+-------+--------------------------+
EXPLAIN
SELECT * FROM words WHERE id>30000 and id < 35000 and word LIKE '%XCX%A';
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | words | range | PRIMARY | PRIMARY | 4 | NULL | 1768 | Using where |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-------------+
我们可以看到第一个查询扫描整个数据集(50976行),而第二个查询只扫描给定ID之间的行(在我的示例中,在30000到35000之间有大约1768行;有很多未使用的ids,但这只是数据创建方式的副作用。)
因此,我们可以看到,通过添加范围,MySQL只需扫描(最差)数据集的五分之一(5000行而不是50000行)。对于如此小的数据集,这不会产生太大的影响,但它会在数据集100上,或者是这个数量的1000倍。
有一点需要注意的是,这两个查询将返回相同的数据集(因为我们知道有效值只能在该id范围内找到),但它们不一定必须返回相同的数据集订购。为了保持一致性,您需要一个ORDER BY子句。
另一件需要注意的事情是,无论如何都没有指向word
(对于此查询),因为'%...'
无法使用索引。