索引覆盖是指如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行,不需要回行到磁盘再找数据。这种查询速度非常快,称为”索引覆盖”
目前创新互联公司已为数千家的企业提供了网站建设、域名、网站空间、绵阳服务器托管、企业网站设计、牡丹网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
1查询频繁 2区分度高 3长度小 4尽量能覆盖常用查询字段
索引长度直接影响索引文件的大小,影响增删改的速度,并间接影响查询速度(占用内存多)。因此对于一些长短不同的字节,我们会针对列中的值,从左往右截取部分,来建索引。但是:
1:截的越短, 重复度越高,区分度越小, 索引效果越不好
2:截的越长, 重复度越低,区分度越高, 索引效果越好,但带来的影响也越大--增删改变慢,并间影响查询速度.
所以,我们要在 区分度 + 长度 两者上,取得一个平衡( distinct 去重 )
select count (distinct left (word,6)) / count (*) from tablename;
对于一般的系统应用区别度能达到 0.1 ,索引的性能就可以接受.
alter table tablename add index word(word(4));
给字符串类型的字段建立索引效率不高,但是必须要经常查这个字段怎么建索引?
比如说一个字段url,类型是字符串。那么可以建一个字段 crcurl 来存储url字段crc32后的值,并给 crcurl 建立索引。
crc32:循环冗余校验。根据网上数据包或计算机文件等数据产生简短固定位数校验码的一种散列函数,主要用来检测或校验数据传输或者保存后可能出现的错误。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。一般来说,循环冗余校验的值都是32位的整数。
crc32 是整形,在MySQL中,给整形字段建立索引效率比较高,crc32虽然不能确保唯一性,但是无碍,相同的机率也是极小,关键是可以大大减少查询的范围,给crcurl这个字段建立索引,查询的时候带上crcurl字段就可以利用到索引。
不允许翻过100页(百度搜索一般到70页左右)
首先我们直接大数据分页limit 5000000,10 发现耗时4.41秒
接下来我们转换方式使用where条件查询,只耗时0.02秒
2次的查询结果不一致,这是因为数据被物理删除过有空洞.,因此我们可以追加软删除功能
分析:优化思路是 不查,少查,查索引,少取.
我们现在必须要查,则只查索引,不查数据,得到id.
再用id去查具体条目. 这种技巧就是延迟索引.
分析:limit是先查询再越过,也就是说我们先查询出所有数据再进行跳跃,上图我们越过500W页,还使用了inner join 内存并没有崩掉,这是因为我们子句tmp临时表中只查询了id(索引覆盖,不需要回行去磁盘找数据了)然后拿到这10个id 分别查询这10条数据 。
排序可能发生2种情况:
1:对于覆盖索引,直接在索引上查询时,就是有顺序的, using index
2:先取出数据,形成临时表做filesort(文件排序,但文件可能在磁盘上,也可能在内存中)
我们的争取目标:取出来的数据本身就是有序的! 利用索引来排序,那么什么时候发生索引排序呢?即查询索引和order by的字段是同一个字段
goods表中 cat_id与shop_price组成联合索引:
select goods_id,cat_id,shop_price from goods where cat_id=4 order by shop_price; 可以直接利用索引来排序,
using where按照shop_price索引取出的结果,本身就是有序的
select goods_id,cat_id,shop_price from goods order by click_count;
using filesort用到了文件排序,即取出的结果再次排序
重复索引是指 在同1个列(如age), 或者顺序相同的几个列(age,school), 建立了多个索引,称为重复索引,重复索引没有任何帮助,只会增大索引文件,拖慢更新速度。
冗余索引是指2个索引所覆盖的列有重叠, 称为冗余索引。比如x,m,列,加索引 index x(x), index xm(x,m) x,xm索引, 两者的x列重叠了, 这种情况,称为冗余索引. (mx, xm 不是重复的,因为列的顺序不一样)
假如你有一个表,
SQL
CREATE
TABLE
test_tab
(2
id
INT,
3
name
VARCHAR(10),
4
age
INT,
5
val
VARCHAR(10)6
);你的业务,有一个查询,是
SELECT
*
FROM
test_tab
WHERE
name
=
一个外部输入的数据
刚开始,数据不多的时候,执行效果还不错。
随着数据量的增加,这个查询,执行起来,越来越慢了。
然后在
name
上面
建立了索引
CREATE
INDEX
idx_test4_name
ON
test_tab
(name
);
这样,
可以加快前面那个查询的速度。
但是,某天,你执行了下面这个SQL,
发现速度又慢了
SELECT
*
FROM
test_tab
WHERE
age
=
25
为啥呢?
因为
age
字段上面,没有索引
索引只在
name
上面有
换句话说,
也就是
WHERE
里面的条件,
会自动判断,有没有
可用的索引,如果有,
该不该用。
多列索引,就是一个索引,包含了2个字段。
例如:CREATE
INDEX
idx_test_name_age
ON
test_tab
(name,
age);那么SELECT
*
FROM
test_tabWHEREname
LIKE
'张%'
AND
age
=
25
这样的查询,将能够使用上面的索引。
多列索引,还有一个可用的情况就是,
某些情况下,可能查询,只访问索引就足够了,
不需要再访问表了。例如:SELECTAVG(
avg
)
AS
平均年龄FROMtest_tabWHEREname
LIKE
'张%'
这个时候,
name
与
age
都包含在索引里面。
查询不需要去检索表中的数据。
SHOW INDEX FROM tbl_name [FROM db_name]
例如,
mysql SHOW INDEX FROM mytable FROM mydb;
mysql SHOW INDEX FROM mydb.mytable;
SHOW KEYS是SHOW INDEX的同义词。您也可以使用mysqlshow -k db_name tbl_name命令列举一个表的索引。
SHOW INNODB STATUS语法
SHOW INNODB STATUS
SHOW INDEX会返回表索引信息。其格式与ODBC中的SQLStatistics调用相似。
SHOW INDEX会返回以下字段:
· Table
表的名称。
· Non_unique
如果索引不能包括重复词,则为0。如果可以,则为1。
· Key_name
索引的名称。
· Seq_in_index
索引中的列序列号,从1开始。
· Column_name
列名称。
· Collation
列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。
· Cardinality
索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。
· Sub_part
如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。
· Packed
指示关键字如何被压缩。如果没有被压缩,则为NULL。
· Null
如果列含有NULL,则含有YES。如果没有,则该列含有NO。
· Index_type
用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。
· Comment
多种评注。