mmd*_*bas 3 mysql performance-testing
我正在阅读tick最大的记录值id.导致执行缓慢的以下查询之间有什么区别?
SELECT tick
FROM eventlog
WHERE id IN (SELECT max(id) FROM eventlog)
Run Code Online (Sandbox Code Playgroud)
SELECT max(id) INTO @id
FROM eventlog;
SELECT tick
FROM eventlog
WHERE id = @id;
Run Code Online (Sandbox Code Playgroud)
CREATE TABLE eventlog (
id INT (11) NOT NULL AUTO_INCREMENT,
tick INT NOT NULL,
eventType_id INT NOT NULL,
compType INT (10) UNSIGNED NOT NULL,
compID INT (10) UNSIGNED NOT NULL,
value_double DOUBLE NOT NULL,
value_int INT (10),
hierarchy_id VARCHAR (255) NOT NULL,
PRIMARY KEY (id),
INDEX htet (
hierarchy_id,
tick,
eventType_id
)
)
Run Code Online (Sandbox Code Playgroud)
试着看一下查询计划,在这种情况下DBMS可能无法使用索引.尝试将查询更改为:
SELECT tick
FROM eventlog
WHERE id = (SELECT max(id) FROM eventlog)
Run Code Online (Sandbox Code Playgroud)
编辑 实际上可能有更好的方法.在上面的查询中,您执行两个INDEX ACCESS操作(如果索引不唯一,则执行一个INDEX RANGE SCAN)和一个TABLE ACCESS.相反,你可以这样做:
SELECT tick
FROM eventlog
ORDER BY id DESC
LIMIT 1
Run Code Online (Sandbox Code Playgroud)
有了这个,应该有一个INDEX ACCESS和一个TABLE ACCESS.实际上,可能存在相当小的差异,因为TABLE ACCESS显然是更昂贵的操作,因此可能会看到差异在大数据集上.
因为in查询不使用索引,所以mysql将扫描所有记录以查找该行.
来自http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html
B树指数特征
B树索引可用于使用=,>,> =,<,<=或BETWEEN运算符的表达式中的列比较.
没有 IN
和
哈希指数特征
散列索引与刚才讨论的特征有些不同:
它们仅用于使用=或<=>运算符的相等比较(但速度非常快).它们不用于比较运算符,例如<找到一系列值.
也没有IN.
正如@tombom所提到foo IN ('bar', 'bla')的那样foo = 'bar' OR foo = 'bla',但是,我认为它们是不同的.所以我在一个有足够数据记录的表上进行测试,并找出以下内容:
mysql> show columns from t_key;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| a | int(11) | NO | PRI | NULL | auto_increment |
| b | int(11) | YES | MUL | NULL | |
+-------+---------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
mysql> select count(a) from t_key;
+----------+
| count(a) |
+----------+
| 989901 |
+----------+
1 row in set (0.00 sec)
mysql> explain select a from t_key where a in (select max(a) from t_key);
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
| 1 | PRIMARY | t_key | index | NULL | PRIMARY | 4 | NULL | 989901 | Using where; Using index |
| 2 | DEPENDENT SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+--------------------+-------+-------+---------------+---------+---------+------+--------+------------------------------+
2 rows in set (0.00 sec)
mysql> explain select a from t_key where a =(select max(a) from t_key);
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
| 1 | PRIMARY | t_key | const | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
| 2 | SUBQUERY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+------------------------------+
2 rows in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
然后我尝试IN使用静态序列查询,它的作用如@tombom所述:
mysql> explain select a from t_key where a in (100,200);
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | t_key | range | PRIMARY | PRIMARY | 4 | NULL | 2 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select a from t_key where a=100 or a=200;
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | t_key | range | PRIMARY | PRIMARY | 4 | NULL | 2 | Using where; Using index |
+----+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
1 row in set (0.00 sec)
Run Code Online (Sandbox Code Playgroud)
我不知道mysql是否会在可能的情况下将IN查询转换为ORs一个(例如,序列在查询之前已知),并且我没有找到相关文档,但是explain在这种情况下它确实扫描了表格.
| 归档时间: |
|
| 查看次数: |
1866 次 |
| 最近记录: |