索引是什么?
① 索引在搜索引擎优化简单解释 指已经被收录且参与关键词排名的页面。
② 索引的通俗解释 索引就像是图书的目录,根据目录中的页码快速找到所需内容。
③ 索引在百度百科中的解释 在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。
创建索引的语法
- 创建索引
IF NOT EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_orderdate')
CREATE NONCLUSTERED INDEX idx_nc_orderdate ON Sales.Orders(orderdate);
GO
- 删除索引
IF EXISTS (SELECT * FROM sysindexes WHERE id=OBJECT_ID('Sales.Orders') AND name='idx_nc_orderdate')
DROP INDEX idx_nc_orderdate ON Sales.Orders;
GO
索引类型
普通索引:仅加速查询
唯一索引:加速查询 + 列值唯一(可以有null)
主键索引:加速查询 + 列值唯一(不可以有null)+ 表中只有一个
组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
全文索引:对文本的内容进行分词,进行搜索
ps.索引合并,使用多个单列索引组合搜索
覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖
mysql数据库优化之 如何选择合适的列建立索引
- 在where 从句,group by 从句,order by 从句,on 从句中出现的列;
- 索引字段越小越好;
- 离散度大的列放到联合索引的前面;比如:
select * from payment where staff_id = 2 and customer_id = 236;
针对上面的查询是 index(sftaff_id, customer_id) 好?
还是index(customer_id, staff_id)好?
因为customer_id的离散度更大,因此用后面的更合适!!
那么问题来了。怎么判断离散度呢,可以使用 select count(distinct customer_id), count(distinct staff_id) from 表名
谁的值大,说明这一些列的离散度更高!
SQL语句索引使用注意事项
1、避免在where子句中使用 is null 或 not null
2、避免在where子句中使用!=或<>操作符
3、避免在where子句中使用or
4、少用 in 或not in
5、like通配符的使用 不要“%11%” 要“11%”
例如LIKE“%name”或者LIKE“%name%”,这种查询会导致索引失效而进行全表扫描。但是可以使用LIKE “name%”。
那么如何解决这个问题呢,答案:使用全文索引。
在我们查询中经常会用到select id,fnum,fdst from dynamic_201606 where user_name like ‘%zhangsan%’; 。这样的语句,普通索引是无法满足查询需求的。庆幸的是在MySQL中,有全文索引来帮助我们。
创建全文索引的SQL语法是:
ALTER TABLE dynamic_201606
ADD FULLTEXT INDEX idx_user_name
(user_name
);
使用全文索引的SQL语句是:
select id,fnum,fdst from dynamic_201606 where match(user_name) against(‘zhangsan’ in boolean mode);
6、避免在where子句中表达式操作 id/2=100 要用id=200
7、避免在where子句中进行函数式操作
8、在子句中使用exists代替in是一个好选择
9、避免在where子句中对字段进行null值判断
对于null的判断会导致引擎放弃使用索引而进行全表扫描。
10、避免隐式类型转换
where子句中出现column字段的类型和传入的参数类型不一致的时候发生的类型转换,建议先确定where中的参数类型。
11、分段查询
在一些用户选择页面中,可能一些用户选择的时间范围过大,造成查询缓慢。主要的原因是扫描行数过多。这个时候可以通过程序,分段进行查询,循环遍历,将结果合并处理进行展示。
12、使用合理的分页方式以提高分页的效率
select id,name from product limit 866613, 20
使用上述SQL语句做分页的时候,可能有人会发现,随着表数据量的增加,直接使用limit分页查询会越来越慢。
优化的方法如下:可以取前一页的最大行数的id,然后根据这个最大的id来限制下一页的起点。比如此列中,上一页最大的id是866612。SQL可以采用如下的写法:
select id,name from product where id> 866612 limit 20
13、区分in和exists、not in和not exists
区分in和exists主要是造成了驱动顺序的改变(这是性能变化的关键),如果是exists,那么以外层表为驱动表,先被访问,如果是IN,那么先执行子查询。所以IN适合于外表大而内表小的情况;EXISTS适合于外表小而内表大的情况。
关于not in和not exists,推荐使用not exists,不仅仅是效率问题,not in可能存在逻辑问题。如何高效的写出一个替代not exists的SQL语句?