几种常见的MySQL优化
指数的相关性1。查询(或更新、删除、可以转换为查询)不用于索引。
这是最基本的步骤,您需要查看索引是否在SQL执行解释的执行计划中使用,并且您需要将焦点放在类型=所有、键= null的字段上。
2。在索引字段上应用函数
to_char(gmt_created,' MMDD)= '0101
正确的写作方式
gmt_created之间to_date(20090101
三.在索引字段上使用完全模糊
member_id像% alibab %
B树不能解决这些问题,你可以考虑搜索引擎。
但member_id喜欢alibab %可用于索引。
事实上,对于任何字段使用类似的% %是不规范的做法,您需要能够检查此错误用法。
4。多栏字段索引,不使用前导索引。
指数:(memeber_id,group_id)
在group_id = 9234,事实上,是没有办法用上述指标的条件。这是一个非常常见的误用。明白你为什么不能用这个指标,你需要了解MySQL构建多柱指数。
索引是B树。问题是,对于多栏索引,MySQL索引字段按索引顺序组装成一个新的字符串,作为构建B树的键,因此在查询条件下,如果不使用前导码,就无法访问多列索引的B树。
索引应该建立:(group_id,member_id)
5。访问索引以外的字段
指数(member_id,主题)
选择主题,从提供member_id = 234
在大量member_id = 234条记录的情况下,这将是比
选择主题,从哪里gmt_created提供member_id = 234
原因是二SQL访问基于ROWID的指数在形成记录。第一SQL使用索引范围扫描得到的结果。
如果SQL执行很多次,但是读取的字段没有被索引覆盖,那么可能需要一个覆盖索引。
6。计数(id)有时比计数(*)慢。
计数(id)= id不为null的计数(1)
如果未索引(id)索引,则使用全表扫描,计数(*)将使用索引的最佳索引进行快速全面扫描。
计数计数(*)的使用
7。停止机构的正确使用
确定是否member_id在提供的记录表:
select count(*)从哪里member_id = 234限1提供
比
select count(*)提供,member_id = 234
原因是第一个SQL在获得第一个记录后会停止。
高效分页
1。高效的分页
使用连接技术,使用索引查找合格ID,构建一个临时表,并使用这个小临时表与原始表进行连接。
选择*
从
(
选择T *,行号为RN
从
(SELECT * FROM blog.blog_article
在domain_id = 1
草案=0
通过domain_id,选秀顺序,gmt_created DESC)T
在行号> = 2
一)
在a.rn < = 3
它应该重写。
选择blog_article *。
从
(
选择抛弃,行号为RN
从
(
选择从blog.blog_article rowid的ID
在domain_id = 1
草案=0
通过domain_id,选秀顺序,gmt_created desc
T)
在行号> = 2
一、blog_article
在a.rn > = 3
和a.rid = blog_article.rowid
2。顺序不用于索引
有索引(A,B,C)
混合排序规则
由ASC、B DESC序、C和混合排序方向 / * * /
失踪的序言
在这里,g = const的顺序是缺少前缀的。
漏中柱
在这里,C顺序的缺缺是。
不在索引中的列用于排序。
其中a,d的常量顺序不是索引的一部分。
主键的有效使用
随机查询
错误的方法:
选择*从标题里kind_id = 1阶伦德(1)限制;
创建标题指数K(kind_id);
此SQL执行一个完整的表扫描,并将数据保存到一个临时表中,这是一个非常耗时的操作。
改进的方法是使用偏移量。
选择圆(rand()*(*)计数)从标题,kind_id = 1;
选择*从哪里kind_id = 1限1美元抵消随机标题;
创建标题指数K(kind_id);
与以前的方法相比,这种方法可以利用在kind_id指数和减少数据块需要扫描的。然而,如果偏移量是非常大的,那么数据块需要扫描也非常大,而极端的情况是,扫描所有的数据块索引K.
使用主键进行范围查找的最佳方法
选择圆(rand()*(*)计数)从标题,kind_id = 1;
选择*从标题里kind_id =和ID >随机限1美元;
此SQL使用范围查询的主键,完全索引,并且只读取一条记录,速度非常快。但是,这种用法的限制是主键必须是int类型的,并且它是不断自我增长的。
高效率的加入
1。小表驱动大表联接
2。避免子查询
子查询是一个潜在的危险,对性能的影响。你应该使用加入重写SQL。
数据类型
1。避免隐式转换
创建表(用户)
` ID ` SmallInt(5)符号的非空auto_increment,
帐户char(11)不是空注释,
`电子邮件` varchar(128),
主键(id),
唯一密钥'用户名'('帐户')
InnoDB引擎= = utf8字符集);
> > > > > >从用户中解释帐户* = 123
*************************** 1。行***************************
编号:1
select_type:简单
表:用户
类型:所有
possible_keys:用户名
关键词:零
key_len:空
参考:空
行数:2
附加:使用在哪里
1行集(0秒)
你可以看到,帐户状态= 123不使用唯一索引`用户名`。MySQL的服务器读取存储引擎的所有记录,并使用to_number()函数在记账变换成数字,和转换后的号码是用来与参数比较。在我们的测试形式有2记录和执行计划中列的值是2,和式的值,这也表明,指数`用户名`是没有用的。
复制代码代码如下:MySQL >解释SELECT * FROM用户帐户= '123 G
*************************** 1。行***************************
编号:1
select_type:简单
表:用户
类型:const
possible_keys:用户名
关键词:用户名
key_len:33
参考:const
行数:1
额外的:
1行集(0秒)
参数是String类型,我们可以看到索引用户名,它是使用的。
这是一种经常被误用的做法。
2。主键不是自添加的。
自添加主键有很多好处:
高插入性能。
减少页面的碎片。
提供两级索引的性能以减少两级索引的空间,因为两级索引存储主键值,而不是页面中的行ID。