解惑

解己之惑,解人之惑

标签:sql

intersect的性能问题

我们有张表是存储用户自定义的类似tag的信息的,有一个功能是按照tag进行搜索,而且支持搜索多个tag查找同时使用这些tag的对象,最开始的实现就是使用的intersect,我感觉可能有问题,然后正好没有太多的事情,就试了下性能,发现那个SQL可以进行改造,变成group by 加 having的模式,一个查询搞定,弄了大概4万条数据,两个SQL(同时查4个Tag)的对比结果显示,前面的SQL会扫描整个表4次(和查询的tag的次数直接相关),并且有一次写入操作,而后面的只有一次扫描没有写入操作,时间上后面的SQL的性能是前者的两倍以上。所以对于同质的SQL的intersect可以转换为这样的group by加having的模式。

原来的SQL:

select ObjectID from ConfigObjectMetaData where KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 6769857814803370866 and ValueInt32 = 2 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = 3984357063977881949 and ValueInt32 = 3 and ObjectType = 10

intersect select ObjectID from ConfigObjectMetaData where KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160 and ObjectType = 10

修改后的:
select ObjectID from ConfigObjectMetaData where ObjectType = 10 and (
(KeyNameHash = -3023837279545376792 and ValueStrHash = -6420380264491338705)
or
(KeyNameHash = 6769857814803370866 and ValueInt32 = 2)
or
(KeyNameHash = 3984357063977881949 and ValueInt32 = 3)
or
(KeyNameHash = -3087541436254450506 and ValueStrHash = -3706752959682952160)
)
group by ObjectID
having count(ObjectID)=4

Inner join的问题

这个是最近感觉最有成就的一个发现了。
我们的系统有一个存储过程执行一个很核心的查询功能,但是在某些情况下非常的慢,而且最近QA一直在做性能测试,每天发送大量的数据,导致系统的性能越来越慢,我原来也曾经优化过这个存储过程,建了很多索引,解决了那个时候管理员用户的问题,但是现在很多普通用户的问题更加的严重,经过调试发现第一步的查询非常的慢,打印出结果来发现那个查询会产生9千万条纪录,而且会使用多达6G的硬盘空间来存储临时数据,后来加了个distinct解决了空间问题,空间使用不到6M,但是速度还是很慢,使用Tuning Advisor优化也没有什么帮助,后来我想了下为什么会产生那么多相同的数据呢?仔细看了下SQL,发现它用6个表进行inner join,但是只从其中的四个表各取一个字段,我就把另外的两个表从inner join移到where条件了,查询时间从6分钟(问题最大的一个用户)减少到6秒,呵呵

© 2024 解惑

本主题由Anders Noren提供向上 ↑