介绍几种我们常用到的sql优化。
开始之前,我们先创建如下表:
CREATE TABLE customer_info(
id INT NOT NULL auto_increment,
name VARCHAR(100) NOT NULL,
birthday DATE NOT NULL,
phone CHAR(11) NOT NULL,
country varchar(100) NOT NULL,
PRIMARY KEY (id),
KEY idx_name_birthday_phone (name, birthday, phone)
);
其中name, birthday, phone是组合索引
避免使用select*,尽量只访问索引中内容
我们可以如下查询:
select name,birthday,phone from customer_info where name='张三';
这样我们在索引数据中就可查询到我们所需的信息。
最佳左前缀法则
对于组合索引,我们的查询条件要从最左边列的开始,索引才会起作用,如下:
select * from customer_info where name='张三';
也可以多个左边的列:
select * from customer_info where name='张三' and birthday='2000-03-05';
如果跳过了左边的列,则索引不会起作用,如:
select * from customer_info where birthday='2000-03-05';
使用join代替子查询
例如如下子查询:
select * from customer_detail_info where customer_id=(select id from customer_info where name='李四');
我们可以改成join的方式:
select detail_info.* from customer_detail_info detail_info
join customer_info info on detail_info.customer_id=info.id
where info.name='李四';
不在索引列上做任何操作
如果我们在索引上进行了表达式操作(计算、函数等),会导致索引失效,如下语句:
SELECT * FROM customer_info where id * 2 = 4;
select * from customer_info where upper(name)='李四';
这些都会导致索引失效,进行全表扫描,应避免这样的查询语句。
like语句使用通配符前缀
like语句应尽量使用通配符前缀(例:where name like ‘李%’)的方式,如下查询:
select * from customer_info where name like'李%';
应避免使用后缀(例:where name like ‘%四’)和全配符(例:where name like ‘%四%’),这些都会导致索引失效。
字符串不加单引号索引失效
select * from customer_info where name = '李四';
对于索引列是字符串的查询若不加单引号,也会导致索引失效。
分组统计可以禁止排序
默认分组查询是会自动排序的,可以通过禁止排序来提高查询效率,可以通过添加ORDER BY NULL来禁止排序:
SELECT name,count(*) FROM customer_info GROUP BY name ORDER BY NULL;
尽量用union all代替union
union操作默认会进行去重(导致额外的内存和cpu消耗),如果不想去重可以使用union all。
批量INSERT插入
对于插入多条数据,应尽量使用批量插入:
INSERT INTO customer_info(name, birthday, phone, country)
VALUES
('张三', '2000-02-02', '18600001111', '中国'),
('李四', '2001-02-02', '18600001111', '中国'),
('王五', '2002-02-02', '18600001111', '中国');