Shu*_*ham 7 mysql database innodb
这是我的表:
在我的桌子上
Clustering_key (主键和自动增量)ID (索引栏)Data (文本数据类型列)Position(索引列)维持的顺序 Data我的表有90,000行,相同ID等于5.我想前3行ID等于5,我的查询是这样的
Select * from mytable where ID=5 Limit 3;
Run Code Online (Sandbox Code Playgroud)
ID 列是索引列所以我认为mysql只扫描前3行但mysql扫描大约42000行.
这里解释查询:
任何可能避免所有行扫描.
请给我一些解决方案
提前致谢
我模拟了这个场景。
创建表 mytable (
Clustering_key INT NOT NULL AUTO_INCRMENT,
ID INT 不为空,
数据文本不为空,
位置 INT NOT NULL,
主键(聚类键),
密钥(ID),
按键(位置)
)
INSERT INTO mytable (ID,数据,位置) VALUES (5,CONCAT("数据-",5), 7);
INSERT INTO mytable (ID,数据,位置) VALUES (5,CONCAT("数据-",5), 26);
INSERT INTO mytable (ID,数据,位置) VALUES (5,CONCAT("数据-",51), 27);
INSERT INTO mytable (ID,数据,位置) VALUES (5,CONCAT("数据-",56), 28);
INSERT INTO mytable (ID,数据,位置) VALUES (5,CONCAT("数据-",57), 31);
mysql> 解释 Select * from mytable where ID=5 Limit 3
+----+-------------+---------+------------+-----+ ---------------+------+---------+--------+--------+-- --------+--------+
| 编号 | 选择类型 | 表| 隔断| 类型 | 可能的键 | 关键| key_len | 参考| 行 | 过滤| 额外 |
+----+-------------+---------+------------+-----+ ---------------+------+---------+--------+--------+-- --------+--------+
| 1 | 简单| 我的表 | 空 | 参考| 身份证 | 身份证 | 4 | 常量 | 5 | 100.00 | 空 |
+----+-------------+---------+------------+-----+ ---------------+------+---------+--------+--------+-- --------+--------+
1 行一组,1 次警告(0.00 秒)
是的,explain显示检查的行数是 5,而不是 3。但这似乎只是一个误导性信息。可以通过以下步骤为所有查询启用慢速日志(设置 long_query_time=0)来验证运行时 rows_examined 的确切数量。
注意:您必须仅在您自己的测试数据库中设置 long_query_time=0。并且测试后必须将参数重置回之前的值。
- 设置全局slow_query_log=1;
- 设置全局long_query_time=0;
- 设置会话long_query_time=0;
mysql> 显示类似“%slow%”的变量;
+-------------------------+--------------------- ----------------------------+
| 变量名 | 价值|
+-------------------------+--------------------- ----------------------------+
| log_slow_admin_statements | 日志慢速管理语句 关闭 |
| log_slow_slave_statements | log_slow_slave_statements | 关闭 |
| 慢启动时间 | 2 |
| 慢速查询日志 | 开 |
| 慢速查询日志文件 | /usr/local/mysql/data/slow.log | /usr/local/mysql/data/slow.log |
+-------------------------+--------------------- ----------------------------+
5 行一组(0.10 秒)
mysql> 选择@@long_query_time;
+--------------------+
| @@long_query_time |
+--------------------+
| 0.000000 | 0.000000
+--------------------+
And then in the terminal, executing the query
<pre>
mysql> Select * from mytable where ID=5 Limit 3;
+----------------+----+---------+----------+
| Clustering_key | ID | Data | Position |
+----------------+----+---------+----------+
| 5 | 5 | Data-5 | 7 |
| 26293 | 5 | Data-5 | 26 |
| 26294 | 5 | Data-51 | 27 |
+----------------+----+---------+----------+
3 rows in set (0.00 sec)
mysql> Select * from mytable where ID=5 Limit 1;
Run Code Online (Sandbox Code Playgroud)
slow_query_log_file通过检查上面打印的内容来检查慢速日志/usr/local/mysql/data/slow.log
您可以通过以下方式了解信息。
# 时间:2019-04-26T01:48:19.890846Z
# 用户@主机: root[root]@localhost[] Id:5124
# Query_time: 0.000575 Lock_time: 0.000146 Rows_sent: 3 Rows_examined: 3
设置时间戳=1556243299;
Select * from mytable where ID=5 限制 3;
# 时间:2019-04-26T01:48:34.672888Z
# 用户@主机: root[root]@localhost[] Id:5124
# Query_time: 0.000182 Lock_time: 0.000074 Rows_sent: 1 Rows_examined: 1
设置时间戳=1556243314;
Select * from mytable where ID=5 限制 1;
运行Rows_exmained时值等于limit参数值。测试在MySQL 5.7.18上完成。
----------------------------------另一种验证方式------------------------ ----------------------
mysql> 显示类似“%Innodb_rows_read%”的状态;
+------------------+------+
| 变量名 | 价值|
+------------------+------+
| Innodb_rows_read | Innodb_rows_read | 13 |
+------------------+------+
一组 1 行(0.00 秒)
mysql> Select * from mytable where ID=5 限制 1;
+----------------+----+--------+----------+
| 聚类_键| 身份证 | 数据| 位置 |
+----------------+----+--------+----------+
| 5 | 5 | 数据5 | 7 |
+----------------+----+--------+----------+
一组 1 行(0.00 秒)
mysql> 显示类似“%Innodb_rows_read%”的状态;
+------------------+------+
| 变量名 | 价值|
+------------------+------+
| Innodb_rows_read | Innodb_rows_read | 14 | 14
+------------------+------+
一组 1 行(0.00 秒)
您可以看到Innodb_rows_read限制 1 只增加了 1。如果执行全表扫描查询,您可以看到该值将增加表的计数。
mysql> 从 mytable 中选择 count(*);
+----------+
| 计数(*)|
+----------+
| 126296 | 126296
+----------+
1 行一组(0.05 秒)
mysql> 显示类似“%Innodb_rows_read%”的状态;
+------------------+--------+
| 变量名 | 价值|
+------------------+--------+
| Innodb_rows_read | Innodb_rows_read | 505204 |
+------------------+--------+
一组 1 行(0.00 秒)
mysql> 从 mytable 中选择 *,其中 Data=“Data-5”;
+----------------+----+--------+----------+
| 聚类_键| 身份证 | 数据| 位置 |
+----------------+----+--------+----------+
| 5 | 5 | 数据5 | 7 |
| 26293 | 26293 5 | 数据5 | 26 | 26
| 26301 | 26301 5 | 数据5 | 7 |
+----------------+----+--------+----------+
3 行一组(0.09 秒)
mysql> 显示类似“%Innodb_rows_read%”的状态;
+------------------+--------+
| 变量名 | 价值|
+------------------+--------+
| Innodb_rows_read | Innodb_rows_read | 631500 | 631500
+------------------+--------+
一组 1 行(0.00 秒)
两种方式都证实了explainfor limit 似乎提供了有关所检查行的误导性信息。
| 归档时间: |
|
| 查看次数: |
431 次 |
| 最近记录: |