17.mysql高级_explain

本文深入探讨了MySQL的查询优化技巧,通过示例解释了如何利用EXPLAIN分析查询执行计划。内容包括创建表、插入数据以及不同ID值对查询顺序的影响,展示了子查询和连接查询的执行顺序与效率。通过对执行计划的分析,读者可以更好地理解查询优化的重要性。

建表

 CREATE TABLE t1(id INT(10) AUTO_INCREMENT,content  VARCHAR(100) NULL ,  PRIMARY KEY (id)); 
 CREATE TABLE t2(id INT(10) AUTO_INCREMENT,content  VARCHAR(100) NULL ,  PRIMARY KEY (id)); 
 CREATE TABLE t3(id INT(10) AUTO_INCREMENT,content  VARCHAR(100) NULL ,  PRIMARY KEY (id));
 CREATE TABLE t4(id INT(10) AUTO_INCREMENT,content  VARCHAR(100) NULL ,  PRIMARY KEY (id));   
 INSERT INTO t1(content) VALUES(CONCAT('t1_',FLOOR(1+RAND()*1000)));  
 INSERT INTO t2(content) VALUES(CONCAT('t2_',FLOOR(1+RAND()*1000)));   
 INSERT INTO t3(content) VALUES(CONCAT('t3_',FLOOR(1+RAND()*1000)));      
 INSERT INTO t4(content) VALUES(CONCAT('t4_',FLOOR(1+RAND()*1000)));

id介绍
id相同,执行顺序由上至下

EXPLAIN select t2.* from t1,t2,t3
where t1.id = t2.id and t1.id = t3.id
and t1.content ='';
+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref              | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
|  1 | SIMPLE      | t1    | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL             |    1 |   100.00 | Using where |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | atguigu_db.t1.id |    1 |   100.00 | NULL        |
|  1 | SIMPLE      | t3    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | atguigu_db.t1.id |    1 |   100.00 | Using index |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
3 rows in set, 1 warning (0.00 sec)

id不同,如果是子查询,id的序号会递增,id值越大优先级越高,越先被执行

EXPLAIN select t2.* from t2 where id =(
	select id from t2 where id = (
		select t3.id from t3 where t3.content='')
	);
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra                          |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+
|  1 | PRIMARY     | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
|  2 | SUBQUERY    | NULL  | NULL       | NULL | NULL          | NULL | NULL    | NULL | NULL |     NULL | no matching row in const table |
|  3 | SUBQUERY    | t3    | NULL       | ALL  | NULL          | NULL | NULL    | NULL |    1 |   100.00 | Using where                    |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+--------------------------------+

explain select t2.* from 
(select t3.id from t3 where t3.content = '') s1, t2
where s1.id = t2.id;

id如果相同,可以认为是一组,从上往下顺序执行;在所有组中,id值越大,优先级越高,越先执行 衍生表 = derived2 --> derived + 2 (2 表示由 id =2 的查询衍生出来的表。type 肯定是 all ,因为衍生的表没有建立索引)

+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
| id | select_type | table | partitions | type   | possible_keys | key     | key_len | ref              | rows | filtered | Extra       |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+
|  1 | SIMPLE      | t3    | NULL       | ALL    | PRIMARY       | NULL    | NULL    | NULL             |    1 |   100.00 | Using where |
|  1 | SIMPLE      | t2    | NULL       | eq_ref | PRIMARY       | PRIMARY | 4       | atguigu_db.t3.id |    1 |   100.00 | NULL        |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------------+------+----------+-------------+

<think>嗯,用户给了一个SQL查询,想要添加去缓存查询,以查看真实的查询时间。首先,我需要理解用户的需求。他们可能是在测试查询性能,或者想要排除缓存对执行时间的影响。需要确认数据库类型,因为不同的数据库管理系统的缓存机制和禁用方法可能不同。 接下来,用户提供的SQL语句涉及多个表的连接,包括左连接和子查询。可能需要先分析现有查询的结构,看看是否有优化空间,但用户的主要需求是禁用缓存来测量真实时间。所以重点应放在如何在不同数据库中禁用查询缓存。 考虑到常见的数据库MySQL、PostgreSQLSQL Server,每个的处理方式不同。例如,MySQL可以使用SQL_NO_CACHE关键字,而PostgreSQL可能需要调整配置参数或者使用pg_stat_statements扩展。SQL Server则可能使用OPTION (RECOMPILE)提示。需要为用户提供多种情况的解决方案,因为他们可能使用不同的数据库系统。 另外,用户可能不太清楚如何具体实施这些方法,所以需要分步骤说明,比如在查询中添加特定的关键字或选项,或者在数据库会话中设置参数。同时,提醒用户在生产环境中谨慎操作,因为禁用缓存可能会影响性能。 还需要考虑用户是否了解如何测量查询时间。可能需要补充说明如何使用数据库的内置工具或命令行工具来测量执行时间,比如MySQL的SHOW PROFILES或EXPLAIN ANALYZE在PostgreSQL中的使用。 最后,确保回答结构清晰,先解释每个数据库的具体步骤,再给出注意事项,确保用户能够安全有效地实现目标。</think>以下是为该SQL查询添加去缓存查询功能并查看真实执行时间的步骤说明: 1. **MySQL数据库解决方案**: ```sql SELECT SQL_NO_CACHE t1.id, t1.version,... /* 保持原有字段列表 */ FROM conflict_info t1 /* 保持原有JOIN条件 */ WHERE ... /* 原有查询条件 */ ``` 2. **PostgreSQL解决方案**: ```sql EXPLAIN ANALYZE -- 会实际执行查询并返回执行计划+耗时 SELECT t1.id, t1.version,... FROM conflict_info t1 /* 保持原有JOIN条件 */ WHERE ... ``` 3. **SQL Server解决方案**: ```sql SELECT t1.id, t1.version,... FROM conflict_info t1 WITH (NOLOCK) /* 保持原有JOIN条件 */ OPTION (RECOMPILE) -- 强制重新编译执行计划 WHERE ... ``` **注意事项**: - 缓存类型差异:不同数据库的缓存机制不同,包含 * 查询结果缓存(如MySQL query cache) * 执行计划缓存 * 数据页缓存(Buffer Pool) - 测量建议: * 连续执行3-5次取平均值 * 首次执行反映冷缓存时间 * 后续执行反映热缓存时间 - 生产环境慎用:`SQL_NO_CACHE`和`NOLOCK`可能影响系统性能 - 高级分析推荐: ```sql SHOW PROFILES; -- MySQL性能分析 SET STATISTICS TIME ON; -- SQL Server耗时统计 EXPLAIN (ANALYZE, BUFFERS) ... -- PostgreSQL详细分析 ``` **原查询优化建议**: 子查询`(SELECT MAX(p.id)...)`可能存在性能瓶颈,建议: ```sql LEFT JOIN ( SELECT conflict_id, MAX(id) AS max_id FROM conflict_flow_path GROUP BY conflict_id ) t3_max ON t1.id = t3_max.conflict_id LEFT JOIN conflict_flow_path t3 ON t3_max.max_id = t3.id ``` 通过以上调整,既可以获取真实查询耗时,又能优化原有查询性能。实际应用中建议结合数据库监控工具进行深度性能分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值