mysqlsql语句优化
❶ 如何用一款小工具大大加速Mysql SQL语句优化
其实MySQL自带查询优化器啊。
explain SELECT id,name from tablename where id = 10;root@localhost [test]>explain select id,k from sbtest1 where id =1000\G*************************** 1. row *************************** id: 1 select_type: SIMPLE table: sbtest1 partitions: NULL type: constpossible_keys: PRIMARY key: PRIMARY key_len: 4 ref: const rows: 1 filtered: 100.00 Extra: NULL1 row in set, 1 warning (0.02 sec)这个就告诉你,这一条语句是如何执行的。possible_keys,只可能会走的索引key:是实际走的索引,这里走的是主键索引哈。sql优化还有很多知识,一般都用这个来查看执行计划。具体细节你需要再去翻看资料。##基础内容可以看看这里。使用MariaDB数据库管理系统。#MariaDB和MySQL使用上大致一样的。
❷ 请问这个MySQL SQL语句如何优化(改写)
user_id和create_time的联合索引并不会对按照user_id分组起作用,还是需要在user_id列上单独创建一个索引,这样group by子句可以使用该索引,where子句当中的条件也会用到该索引,查询效率应该会得到显着提升,不妨一试。
❸ mysql如何优化以下语句,查询耗时太久了
一般进行性能分析,分如下三步:
首先需要使用慢查询日志功能,去获取所有查询时间比较长的SQL语句
其次查看执行计划查看有问题的SQL的执行计划 explain
最后可以使用show profile查看有问题的SQL的性能使用情况
慢查询日志分析
首先我们要使用慢查询日志,因为它收集了查询时间比较长的SQL语句,但使用之前必须开启慢查询日志,在配置文件my.cnf(一般为/etc/my.cnf)中的[mysqld] 增加如下参数:
slow_query_log=ONlong_query_time=3slow_query_log_file=/var/lib/mysql/slow-log.log复制代码
增加这些参数之后,重启MySQL,可以进行查询慢查询日志是否开启。
1. 任何地方都不要使用 select * from t,用具体的字段列表代替“*“,不要返回用不到的任何字段。
2. 索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
3. 并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
4. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
5. 尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
6. 如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
7. 对查询进行优化,应尽量避免全表扫描,首先应考虑在 where和order by相关的列上建立索引。
8. 应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。
例如: select * from t where num is null
我们可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select * from t where num=0。
❹ mysql的sql语句优化5种方式
只有5种吗?我知道十种以上的说。
索引(没我得全表查询了)
改变数据储引擎(MyISAM没事务再也不用担心锁表了)
增加冗余数来减少连表查询数(消耗硬盘空间减少CPU使用)
调整查询顺序减少查询量优先(数量少了连表的笛卡儿积也少了)
全文索引(文字长度有限制,而且IO使用量会大增,但是妥妥的快)
查询尽量不要用函数(函数可是不走索引的哦亲)
查询变量类型要提前对好减少系统负担(我提前改变了系统你就不用检测了)
升级服务器硬件(没什么是氪金解决不了的)
配置好临时表空间,合理理由临时表减少主表查询抢资源(唯我独查)
合理理由函数减少系统的判断(明明都能确认内容不同你用UNION 系统还是傻傻的查一遍是否重复UNION ALL则跳过这个步骤同理 inner join 和 left join 也一样)
强制走索引(复合索引的情况有时候手动走比系统判断要好哦)
脏读、幻读等(你堵车我绕路)
数据归档,迁移(没用的数据要进仓哦,别占着主表的资源)
表的碎片整理(迁移后碎片整理更健康哦亲)
索引重构(数据都走了索引也应该重构一下才能保证速度哦)
善用存储过程(串N个表(N大于10)的查询千万别一个SQL到底,分布式查询在吧结果集合并吧骚年)
预处理数据(mysql也有job哦,对于经常要子查询的数据可以先弄个明细表根据主表在后台进行补完,查询的时候就更方便了)
懒得说了。。。。。。。。。。。。。。。。。。
❺ mysql 求大神优化sql语句
可以这样写成只使用1个子查询:
select a.* ,b.d as day_num,b.m as month_num,b.y as year_num
from watersku a,(select sum(b.num) as y,
sum(case when date_format(b.add_time,'%Y-%m')=date_format(now(),'%Y-%m')
then b.num else 0 end) as m,
sum(case when date_format(b.add_time,'%Y-%m-%d')=date_format(now(),'%Y-%m-%d')
then b.num else 0 end) as d
from tra_order b , tra_trade b0
where a.sku_id = b.sku_id and b.tids = b0.tid and b0.status > 2 and date_format(b.add_time,'%Y')=date_format(now(),'%Y'))b
另外上述按当前年、月、系统日期筛选比较表达式,也可以直接用year,month函数替代format函数进行比较,也许效率会高一些。
至于哪些写法的效率高一点,很多时候实际情况与我们想象有较大差距,有时我们认为效率低的写法执行效率并不会比我们认为高的写法低很多,甚至有可能掉反过来,对于这一点我在实际工作中深有体会。稳妥一些的做法是查看SQL执行计划,当然更为可靠的办法是使用大数据表进行实测比较。
❻ mysql 优化包括哪些内容
mysql的优化大的有两方面:
1、配置优化
配置的优化其实包含两个方面的:操作系统内核的优化和mysql配置文件的优化
1)系统内核的优化对专用的mysql服务器来说,无非是内存实用、连接数、超时处理、TCP处理等方面的优化,根据自己的硬件配置来进行优化,这里不多讲;
2)mysql配置的优化,一般来说包含:IO处理的常用参数、最大连接数设置、缓存使用参数的设置、慢日志的参数的设置、innodb相关参数的设置等,如果有主从关系在设置主从同步的相关参数即可,网上的相关配置文件很多,大同小异,常用的设置大多修改这些差不多就够用了。
2、sql语句的优化
1、 尽量稍作计算
Mysql的作用是用来存取数据的,不是做计算的,做计算的话可以用其他方法去实现,mysql做计算是很耗资源的。
2.尽量少 join
MySQL 的优势在于简单,但这在某些方面其实也是其劣势。MySQL 优化器效率高,但是由于其统计信息的量有限,优化器工作过程出现偏差的可能性也就更多。对于复杂的多表 Join,一方面由于其优化器受限,再者在 Join 这方面所下的功夫还不够,所以性能表现离 Oracle 等关系型数据库前辈还是有一定距离。但如果是简单的单表查询,这一差距就会极小甚至在有些场景下要优于这些数据库前辈。
3.尽量少排序
排序操作会消耗较多的 CPU 资源,所以减少排序可以在缓存命中率高等 IO 能力足够的场景下会较大影响 SQL的响应时间。
对于MySQL来说,减少排序有多种办法,比如:
通过利用索引来排序的方式进行优化
减少参与排序的记录条数
非必要不对数据进行排序
4.尽量避免 select *
在数据量少并且访问量不大的情况下,select * 没有什么影响,但是量级达到一定级别的时候,在执行效率和IO资源的使用上,还是有很大关系的,用什么字段取什么字段,减少不必要的资源浪费。
之前遇到过因为一个字段存储的数据比较大,并发高的情况下把网络带宽跑满的情况,造成网站打不开或是打开速度极慢的情况。
5.尽量用 join 代替子查询
虽然 Join 性能并不佳,但是和 MySQL 的子查询比起来还是有非常大的性能优势。MySQL 的子查询执行计划一直存在较大的问题,虽然这个问题已经存在多年,但是到目前已经发布的所有稳定版本中都普遍存在,一直没有太大改善。虽然官方也在很早就承认这一问题,并且承诺尽快解决,但是至少到目前为止我们还没有看到哪一个版本较好的解决了这一问题。
6.尽量少 or
当 where 子句中存在多个条件以“或”并存的时候,MySQL 的优化器并没有很好的解决其执行计划优化问题,再加上 MySQL 特有的 SQL 与 Storage 分层架构方式,造成了其性能比较低下,很多时候使用 union all 或者是union(必要的时候)的方式来代替“or”会得到更好的效果。
7.尽量用 union all 代替 union
union 和 union all 的差异主要是前者需要将两个(或者多个)结果集合并后再进行唯一性过滤操作,这就会涉及到排序,增加大量的 CPU 运算,加大资源消耗及延迟。所以当我们可以确认不可能出现重复结果集或者不在乎重复结果集的时候,尽量使用 union all 而不是 union。
8.尽量早过滤
这一优化策略其实最常见于索引的优化设计中(将过滤性更好的字段放得更靠前)。
在 SQL 编写中同样可以使用这一原则来优化一些 Join 的 SQL。比如我们在多个表进行分页数据查询的时候,我们最好是能够在一个表上先过滤好数据分好页,然后再用分好页的结果集与另外的表 Join,这样可以尽可能多的减少不必要的 IO 操作,大大节省 IO 操作所消耗的时间。
9.避免类型转换
这里所说的“类型转换”是指 where 子句中出现 column 字段的类型和传入的参数类型不一致的时候发生的类型转换:
A:人为在column_name 上通过转换函数进行转换
直接导致 MySQL(实际上其他数据库也会有同样的问题)无法使用索引,如果非要转换,应该在传入的参数上进行转换
B:由数据库自己进行转换
如果我们传入的数据类型和字段类型不一致,同时我们又没有做任何类型转换处理,MySQL 可能会自己对我们的数据进行类型转换操作,也可能不进行处理而交由存储引擎去处理,这样一来,就会出现索引无法使用的情况而造成执行计划问题。
以上两种情况在开发者因为某种原因经常会有,本来可以用到索引的结果类型不对没有用到索引,或是因为类型不对又有越界的情况发生造成无法使用索引的情况,结果造成很严重的事故。
10.优先优化高并发的 SQL,而不是执行频率低某些“大”SQL
对于破坏性来说,高并发的 SQL 总是会比低频率的来得大,因为高并发的 SQL 一旦出现问题,甚至不会给我们任何喘息的机会就会将系统压跨。而对于一些虽然需要消耗大量 IO 而且响应很慢的 SQL,由于频率低,即使遇到,最多就是让整个系统响应慢一点,但至少可能撑一会儿,让我们有缓冲的机会。
11.从全局出发优化,而不是片面调整
SQL 优化不能是单独针对某一个进行,而应充分考虑系统中所有的 SQL,尤其是在通过调整索引优化 SQL 的执行计划的时候,千万不能顾此失彼,因小失大。
12.尽可能对每一条运行在数据库中的SQL进行 explain
优化 SQL,需要做到心中有数,知道SQL 的执行计划才能判断是否有优化余地,才能判断是否存在执行计划问题。在对数据库中运行的 SQL 进行了一段时间的优化之后,很明显的问题 SQL 可能已经很少了,大多都需要去发掘,这时候就需要进行大量的 explain 操作收集执行计划,并判断是否需要进行优化。
❼ mysql如何优化以下语句,查询耗时太久了
根据所描述的问题,可尝试在mms_profitcenter 的FOrderID ,FSuffix列上建立索引,再查询试试。 下面提供30种mysql常用优化方法供参考:
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
select id from t where num=0
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num=10 or num=20
可以这样查询:
select id from t where num=10
union all
select id from t where num=20
5.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
若要提高效率,可以考虑全文检索。
6.in 和 not in 也要慎用,否则会导致全表扫描,如:
select id from t where num in(1,2,3)
对于连续的数值,能用 between 就不要用 in 了:
select id from t where num between 1 and 3
7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
select id from t where num=@num
可以改为强制查询使用索引:
select id from t with(index(索引名)) where num=@num
8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where num/2=100
应改为:
select id from t where num=100*2
9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询,如需要生成一个空表结构:
select col1,col2 into #t from t where 1=0
这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
create table #t(...)
13.很多时候用 exists 代替 in 是一个好的选择:
select num from a where num in(select num from b)
用下面的语句替换:
select num from a where exists(select 1 from b where num=a.num)
14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
30.尽量避免大事务操作,提高系统并发能力。