‘壹’ 核销明细查询in条件过多导致sql超时优化
现状:查询条件中in条件包含了400+门店的条件 且是返回全表字段,需要排序+分页查询 优化:(前提,做数据归档) 1.将大量门店查询拆分成 50个门店一次查询 ,且只查询主键id,通过分次查询将查询到的数据汇总(此时数据可能会有上万 但只包含主键id) 2.根据分页条件去其中符合条件的主键id (此时安分页筛选出来的数据一般10-30个) 3.根据筛选出的主键id通过in条件查询符合条件的数据返回‘贰’ mysql多条件查询的优化
如果对查询要求高,可使用myisam.
几个优化建议:
(1)适当的建立字段索引。
(2)注意sql条件的顺序,把能够排除掉大量数据的条件写在前面。
‘叁’ sql调优的几种方式
你好,
SQL优化的一些方法
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。
3.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描。
5.in 和 not in 也要慎用,否则会导致全表扫描,
6.下面的查询也将导致全表扫描:
select id from t where name like '%abc%'
7.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。
8.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。
9.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
10.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
‘肆’ mssql sql语句多条件查询优化问题。
很简单,最终查询的结果是新闻,所以新闻表是你的主要查询表
企业、品牌、媒体这三个都是条件
我认为,你的新闻表中应该有两种形式,
一是同时包括三种条件,包括企业、品牌、媒体代码、新闻标题、内容等关键字段
查询的时候sql语句非常简单,就是select 新闻 from 新闻表 where 企业 in (条件)or 品牌 in (条件)or 媒体 in (条件)
这样一个不好就是新闻库过大,但是因为没有做表关联查询,所以速度非常快
二是仅包括一种条件,新闻分别在3个表中保存
查询的时候需要union联合查询,这样的优势是每个表都相对较小,如果用户只查询一个条件,那查询工作量会非常低。
select 新闻 from 新闻表1 where 企业 in (条件)
union select 新闻 from 新闻表2 where 品牌 in (条件)
union select 新闻 from 新闻表3 where 媒体 in (条件)
好了,你会发现,通过这两种sql,实际上主要工作集中在前台界面的开发上,需要能根据用户的选择有效地拼写sql语句。
至于用户权限,这个是权限表的事情,与查询结果的速度无关,只涉及到能生成哪些条件
不明白再问我
‘伍’ SQL语句中的多个OR该怎么来优化
与或非是逻辑判断的必须,如果真的需要很多or来判断,那么谁也没有办法。
一般优化or的办法是,减少or,也就是减少判断条件。这个不仅仅是数据库的问题,需要从业务等多方面来考虑。
比如,业务可以减少一个or,那么这就是最好的优化方式。
如果几个or字段都有索引,那么可以考虑分开查询,这样能走索引,因为or不走索引。也算优化。
缩小查询范围也算,虽然还是or,还是那么多条件,但是其他条件却可以,让数据量从10w,变为5千,这也是优化。
至于其他的方法,什么换个写法等等,大多数都是扯淡,没什么实际意义。
‘陆’ sql多条件查询,如何高效组合多个条件
多条件查询还是不定条件查询?
多条件查询,要注意OR的运用,同一栏位多个OR的情况会影响效率的。
另外主要的固定条件,比如单号,集团号等建立索引。在其基础上多用加几个AND都没有问题。
子查询、函数等不合算做查询条件。这个也会根据数量量大小而影响效率。
‘柒’ Sql优化-多like模糊查询及根据时间排序
2020-04-21
记录一次sql优化记录:
环境:用的mysql版本 select Version();
优化过程:
用的是两张表联查,四个条件like查询 ,根据时间排序降序
其中A,B表没有大字段,A表20万多数据,B表50万多条数据。语句如下:
EXPLAIN
SELECT A.bondId,A.sname,A.cname,A.secuCode,A. ISSUER,A.guarantor,B.underwriter AS infoSource
FROM A
LEFT JOIN B ON B.bondId = A.bondId
WHERE B.agentType = 1
AND B.underwriter = '有限公司'
AND A.startDate <= '2020-04-21 18:02:10'
AND A.endDate >= '2020-04-21 18:02:10'
AND (
A.cname LIKE '%%' OR A.sname LIKE '%%' OR A.secuCode LIKE '%%'
OR A. ISSUER LIKE '%%'OR A.guarantor LIKE '%%')
AND A.isValid = 1
ORDER BY A.startDate DESC
LIMIT 0, 20
这是2个表都没有加索引的情况,从explain来看结果非常糟糕,都是全表扫描,并且产生临时表同时有文件排序,效率肯定非常低。
首先尝试在B表上建立一个联合索引
可以考虑从关联字段及where条件字段考虑(bondId, underwriter, agentType)
建一个联合索引,试试。
ALTER TABLE B ADD INDEX bua_index(bondId, underwriter, agentType)
再explain看:
可以看到B表用到了我们刚刚建的联合索引,并且额外信息是Using index ,type是ref级别的,效果比较理想,再来看A表。
Where条件中有多个like,这种情况下一般索引都是不可用的,所以必须用覆盖索引解决,
由于又根据startDate排序,所以尝试根据如下字段建立联合索引,同时查询的字段就是索引中的字段(startDate, endDate,cname, sname, secuCode, issuer, guarantor)
ALTER TABLE A ADD INDEX index_scssig(startDate, endDate,cname, sname, secuCode, issuer, guarantor)
再次explain看看效果:
这样乍看上去A表也用到了刚刚建的联合索引,并且type是range级别虽然比ref差点,按理说应该也还可以,但是我执行sql语句,效率还是非常差,查询耗时达到8s,并且偶尔还不止这个时间
究其原因,虽然使用了索引,但是extra里面是Using index condition&Using where
回表操作了,我在想如果将extra优化成Using index效率肯定没问题
故再进一步优化,还是从索引入手
在联合索引上添加2个字段isValid, bondId 再试试
ALTER TABLE A ADD INDEX index_scssig(isvalid,startDate, endDate,cname, sname, secuCode, issuer, guarantor,bondId)
再次explain:
这个结果就是我想要的,然后执行sql看看效率:
已经提升了很多了,但是我试了别的查询条件偶尔时间会到3,4s,怀疑和自己的机器有关
在这这种多个like的or查询mysql本身并不擅长,无奈坑爹的需要需要这样,可能效率并不是非常的高,优化成这样可以接受了。
最近对以前项目的慢查询进行sql调优,感觉性能的下降往往还是sql语句及索引的建立的问题,explain是很有帮助,正确优化还是能极大提升效率的。
‘捌’ 如何进行SQL性能优化
这里分享下mysql优化的几种方法。
1、首先在打开的软件中,需要分别为每一个表创建 InnoDB FILE的文件。
‘玖’ sql 提高多条件查询效率
可建立一个类别表:CREATE TABLE 类别表(产品编号 char(1),类别 char(20));
再与类别表查询;或在原表增加此2个字段。
另外:插入临时表(以substring(产品编号,1,1)为组)
select distict substring(产品编号,1,1), RTRIM(left(CONVERT(varchar(5), 日期, 0),2)) + ''月'' as 月份,CONVERT(varchar(100),日期,23) as 日期,单号,发货人,收货人, sum(abs(数量))as 数量 ,单价, sum(金额) as 金额 from '+ @ckgs +' where substring(产品编号,1,1) like '''+ @cpfl +''' and 单据分类 like '''+@djfl+''' and 产品名称 like '''+@cpmc+''' and 发货人 like '''+@ffr +''' and 收货人 like ''' +@sfr+''' group by 日期,单号,substring(产品编号,1,1), 发货人,收货人,单价 into temp;
再查询temp表。