当前位置:首页 » 编程语言 » mysql优化sql语句

mysql优化sql语句

发布时间: 2023-08-29 13:20:07

sql优化(二)

SQL优化一: sql优化(一)

上片文章已经详细介绍了explain各个字段的含义,以及什么情况应该建立索引,什么情况不需要建立索引以及sql语句性能的判断依据,接下来我介绍下如何合理的建立索引。

sql语句:select id,author_id from article where category_id = 1 and comments>1 order by views desc limit 1;

分析:首先我们根据where后面的条件建立符合索引,然后根据order by后面的字段建立索引,因此建立索引idx_article_ccv,即以(category_id,comments,views)数据列建立复合索引,但由于comments是一个范围,按照BTree索引的原理,先排序category_id,如果遇到相同的category_id则再排序comments,如果遇到相同的comments则再排序views,又因为comments字段在复合索引里处于中间位置,而comments>1是一个条件(是一个范围值),在复合索引的一个范围值的数据列后面的索引全部失效,mysql无法利用索引再对后面的views部分进行检索,也就是说views无法按照索引排序,所以explain下此sql语句,type为range,extra使用的是Using filesort,这是比较糟糕的。所以我们放弃comments这个范围字段,建立索引idx_article_cv,即以(category_id,views)数据列建立复合索引,explain 此sql,type变成了ref,extra的using filesort也变成了using index,这就变得好多了。

索引:idx_article_cv,即以(category_id,views)数据列建立复合索引

前段时间做了一个销售精细化项目,是公司crm项目的一个大模块,大致就是为销售人员制定指标,实现销售目标从区域到团到业务员到客户,实时跟踪业务员所负责客户的下单量的情况。这就存在许多关联关系,区域-团,团-业务员,业务员-客户,这使得sql常常需要关联多张表。

sql语句:SELECT

tu.fuserid,

tu.faccount,

tu.fphone,

tu.fcertificationtype,

tu.fcertificatename,

tu.fkeyarea,

tu.fkeyareatext,

DATE_FORMAT(tcr.fupdatetime,'%Y-%m-%d %H:%i:%s') as fupdatetime,

tag.forggroupid,

tag.forggroupname,

tug.forguserid,

tug.fusername,

tug.fuserphone,

tag.fcitycode

FROM t_finedt_user AS tu

LEFT JOIN t_finedt_customer_relation AS tcr

ON tu.fuserid = tcr.fuserid

LEFT JOIN t_finedt_usergroup AS tug

ON tcr.forguserid = tug.forguserid

and tcr.forggroupid = tug.forggroupid

LEFT JOIN t_finedt_areagroup AS tag

ON tug.forggroupid = tag.forggroupid

where tu.fkeyarea=? and tu.fuserid=? and tug.forggroupid = ?

分析:上面的sql是左连接,左边的表一定是全表查询,所以要建立右边表对应关联字段的索引,在表t_finedt_user上建立tu_fuserid_fkeyarea索引,即以(fuserid,fkeyarea)字段建立索引,在表t_finedt_customer_relation 上建立tcr_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_usergroup 上建立tug_forguserid_forggroupid索引,即以(forguserid,forggroupid)字段建立索引,在表t_finedt_areagroup上建立tag_forggroupid索引,即以(forggroupid)字段建立索引。建立索引后,sql查询速度明显快了很多

索引:tcr_forguserid_forggroupid,tu_fuserid_fkeyarea,tug_forguserid_forggroupid,tag_forggroupid

1、尽可能减少join语句中的NestedLoop的循环次数,永远用小结果集驱动大结果集

2、优先优化NestedLoop的内层循环

3、保证join语句总被驱动表上的join字段已经被索引

4、当无法保证被驱动表join条件字段被索引,且内存资源充足的前提下,不要太吝啬joinBuffer的设置

1、全值匹配我最爱

2、最佳左前缀原则——如果索引了多列,要遵守最左前缀原则,指的是查询从索引的最左前列开始并且不跳过索引中的列

3、并在索引列上做任何操作(计算、函数、自动or手动类型转换),这些会导致索引失效而转向全表扫描

4、存储引擎不能使用索引中范围条件右边的列,范围之后的索引全失效

5、尽量使用覆盖索引(之访问索引的查询(索引列和查询的列一致)),减少select *

6、mysql在使用不等于(!=、>、<)的时候无法使用索引会导致全表扫描。

7、is null、is not null也无法使用索引。

8、like以通配符开头("%abc.."),mysql索引失效也会变成全表扫描的操作。

9、字符串不加单引号也会引起索引失效

10、少用or,用它来连接时会索引失效。

1、对于单值索引,尽量选择针对当前query过滤性更好的索引

2、在选择组合索引的时候,当前query中过滤性最好的字段在索引字段顺序中,位置越靠前越好

3、在选择组合索引的时候,尽量选择尽可能包含当前query中的where字句中更多字段的索引

4、尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。

全值匹配我最爱,最左前缀要遵守

带头大哥不能死,中间兄弟不能断

索引列上少计算,范围之后全失效

like百分写最右,覆盖索引不写里

不等空值还有or,索引失效要少用

var引号不可丢,sql高级也不难

❷ MySQL数据库优化都包括哪些项目

此文章主要向大家介绍的是MySQL数据库优化 其中还包括MySQL数据库的性能优化 常用的SQL语句的优化以及MySQL数据库对INSERT语句进行优化的实际操作方案的描述 望你会有所收获

MySQL InnoDB 的性能问题讨论

MySQL性能优化

InnoDB delete from xxx速度暴慢原因

推荐圈子: mysql研究

更多相关推荐 定期分析表和检查表

分析表的语法如下

引用

ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb _name[ tbl_name]

以上语句用于分析和存储表的关键字分布 分析的结果将可以使得系统得到准确的统计信息 使得SQL能够生成正确的执行计划 如果用户感觉实际执行计划并不是预期的执行计划 执行一次分析表可能会解决问题 在分析期间 使用一个读取锁定对表进行锁定 这对于MyISAM DBD和InnoDB表有作用

例如分析一个数据表

引用

*** yze table table_name

检查表的语法如下

引用

CHECK TABLE tb _name[ tbl_name] [option] option = {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}

检查表的作用是检查一个或多个表是否有错误 CHECK TABLE 对MyISAM 和 InnoDB表有作用 对于MyISAM表 关键字统计数据被更新

CHECK TABLE 也可以检查视图是否有错误 比如在视图定义中被引用的表不存在

定期优化表

MySQL数据库优化表的语法如下

引用

OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tb _name [ tbl_name]

如果删除了表的一大部分 或者如果已经对含有可变长度行的表(含有 VARCHAR BLOB或TEXT列的败宏表)进行更多更银枯亩改 则应使用OPTIMIZE TABLE命令来进行表优化 这个命令可以将表中的空间碎片进行合并 并且可以消除由于删除或者更新造成的空间浪费 但OPTIMIZE TABLE 命令只对MyISAM BDB 和InnoDB表起作用

例如 optimize table table_name

锋森注意 *** yze check optimize执行期间将对表进行锁定 因此一定注意要在数据库不繁忙的时候执行相关的操作

常用的SQL优化

我们在开发的时候常常用到的SQL语句 无非是INSERT GROUPBY等等 对于这些SQL语句 我们怎么进行优化?

大批量插入数据

当用load命令导入数据的时候 适当的设置可以提高导入的速度

对于MyISAM存储引擎的表 可以通过如下方式快速的导入大量的数据

引用

ALTER TABLE tb _name DISABLE KEYS;

loading the data

ALTER TABLE tb _name ENABLE KEYS;

DISABLE KEYS 和 ENABLE KEYS 用来打开或者关闭MyISAM表非唯一索引的更新 在导入大量的数据到一个非空的MyISAM表时 通过设置这两个命令 可以提高导入的效率

对于导入大量的数据到一个空的MyISAM表时 默认就是先导入数据然后才创建索引的 索引不用进行设置

引用

load data infile /home/mysql/text_txt into table text

对于InnoDB类型的表 这种方式不能提高导入数据的效率 但也有几种针对InnoDB类型的表进行MySQL数据库优化的方式

因为InnoDB类型的表式按照主键的顺序保存的 所以将导入的数据按照主键的顺序排序 可以有效提高导入数据的效率

在导入数据前执行 SET UNIQUE_CHECKS= 关闭唯一性校验 在导入结束后执行SET UNIQUE_CHECKS= 恢复唯一性校验 可以提高导入的效率

如果应用使用自动提交的方式 建议在导入前执行SET AUTOMIT= 关闭自动提交 导入结束后执行SET AUTOMIT= 打开自动提交 也可以提高导入效率

MySQL数据库优化INSERT语句

当进行数据INSERT的时候 可以考虑采用以下几种方式进行优化

如果同时从一个客户插入很多行 尽量使用多个值表的INSERT语句 这种方式将大大缩短客户端与数据库的链接 关闭等消耗 使得效率比分开执行的单个INSERT语句快

例如

insert into test values( )

insert into test values( )

insert into test values( )

将上面三句改为:insert into test values( ) ( ) ( )

如果从不同客户插入很多行 能通过使用INSERT DELAYED 语句得到更高的速度

DELAYED 的含义是让INSERT 语句马上执行 其实数据都被放在内存的队列中 并没有真正写入磁盘 这比每条语句分别插入要快得多 LOW_PRIORITY刚好相反 在所有其他用户对表的读写完后才进行插入

将索引文件和数据文件分在不同的磁盘上存放

如果进行批量插入 可以增加bulk_insert_buffer_size变量值的方法来提高速度 但是 这只能对于MyISAM表使用

当从一个文本文件中装载一个表时 使用LOAD DATA INFILE 这通常比使用很多insert语句快 倍左右

lishixin/Article/program/MySQL/201311/29324

热点内容
编程课v 发布:2025-02-04 08:45:00 浏览:103
模拟器能有手机脚本么 发布:2025-02-04 08:39:50 浏览:755
android显示html图片 发布:2025-02-04 08:35:31 浏览:791
如何查学信网账号及密码 发布:2025-02-04 08:33:55 浏览:501
linux32位jdk 发布:2025-02-04 08:33:55 浏览:246
康佳服务器连接失败是怎么回事 发布:2025-02-04 08:18:51 浏览:916
编译编译有什么 发布:2025-02-04 08:05:52 浏览:735
让外网访问内网服务器 发布:2025-02-04 08:02:20 浏览:783
奶块脚本菜地 发布:2025-02-04 07:46:35 浏览:238
条形码识别源码 发布:2025-02-04 07:45:55 浏览:457