优秀SQL查询的11条设计指南

14 篇文章 0 订阅
8 篇文章 0 订阅

《数据库管理基础教程.Jeffrey A.Hoffer》

1. 理解索引在查询处理中是怎样使用的。

很多DBMS 一次查询只能使用一个索引,如mysql。—— 如果经常需要同时对两个字段进行AND查询,那么使用两个单独索引不如建立一个复合索引,因为两个单独索引通常数据库只能使用其中一个,而使用复合索引因为索引本身就对应到两个字段上的,效率会有很大提高。

* 可以使用EXPLAIN命令查看查询计划。

use sqlteacher;
-- 创建表,带两个索引
CREATE TABLE `t_lesson` (
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `start_course_time` DATETIME NOT NULL COMMENT '预计直播课上课时间',
    `end_course_time` DATETIME NOT NULL COMMENT '预计直播课下课时间',
    `city_id` INT(11) NOT NULL,
    PRIMARY KEY (`id`),
    INDEX `idx_city_id` (`city_id`),
    INDEX `idx_start_course_time` (`start_course_time`)
);

-- 查看and查询使用的索引,只会用到一个索引
explain select * from t_lesson where start_course_time = '2019-08-25 06:00:00' and city_id=4;

2. 保持优化器(Query Optimizer)统计信息最新。

在一个特定的查询中,使用索引可能加快速度,也可能减慢速度,所以DBMS要对使用索引的效果做一个预测,预测的依据就是统计信息。一些DBMS不是自动更新统计信息。如果性能退化,就强制运行一个类似更新统计信息的命令。

* 学习查询优化器。

3. 对查询中的字段和文字使用兼容数据类型。避免查询处理中转换数据。

4. 编写简单查询。

5. 将复杂分离为多个简单的部分。

因为DBMS可能在每个查询中只使用一个索引,所以将复杂查询分离为多个简单的部分(每个查询都可以用到索引),然后将结果合并在一起会更好。

6. 不要把一个查询嵌套到另一个中(效率不会更高)。

7. 不要把表和它本身合并。

避免使用自连接。通常为表制作一个临时拷贝并关联原来的表和临时表会更好,查询更高效。

8. 为多个查询创建临时表。

这样做的不足是在查询运行中原始表的更新不会改变临时调。但是对于多个查询都要引用同样的数据子集的情况下,临时表高效。

9. 合并更新操作。

如果可能,可将多个更新命令合并到一个中。这将会减少查询处理的负载并允许DBMS找寻并行处理更新的方式。

-- 更新合并
update t_lesson set end_course_time = '2020-09-29 09:00:00', start_course_time = '2020-08-29 09:00:00' where city_id = 203;

-- 更新合并
update t_lesson set end_course_time = '2021-09-29 09:00:00' where city_id = 203;
update t_lesson set end_course_time = '2022-09-29 09:00:00' where city_id = 204;
update t_lesson set end_course_time=(case city_id when 203 then '2021-09-29 09:00:00' when 204 then '2022-09-29 09:00:00' end) where city_id in (203, 204) 

-- 插入和更新合并
ALTER TABLE t_lesson CHANGE id id BIGINT(20) unsigned not null; -- 去除主键自增属性
ALTER TABLE t_lesson DROP PRIMARY KEY ,ADD PRIMARY KEY ( `city_id` ); -- 修改主键
-- UPDATE和INSERT语句合并,先执行insert into插入语句,如果插入失败(UNIQUE索引或pk重复,说明该条记录已存在),则执行update更新语句;
INSERT INTO t_lesson(id, start_course_time, end_course_time, city_id) VALUES(4, '2019-08-25 06:00:00','2020-09-29 06:00:00', 403) ON DUPLICATE KEY UPDATE start_course_time = '2021-11-11 09:00:00'; 


10. 只检索你需要的数据。

   SELECT * FROM EMP之类的简写尽量避免。

11. 排序时尽量使用索引。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值