执行时间为22秒,返回180行
et_d_JobInfo表里的数据量有60万,字段数有40个
et_s_Comp表里的数据量有20万,字段数有33个
我想达到的速度在5秒里面,不知道有没有希望?SELECT ji.[iID] AS ID
FROM et_d_JobInfo ji,et_s_Comp c
WHERE ji.iCompID = c.[iID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND ji.[iID]
NOT IN (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
ORDER BY ID DESC
et_d_JobInfo表里的数据量有60万,字段数有40个
et_s_Comp表里的数据量有20万,字段数有33个
我想达到的速度在5秒里面,不知道有没有希望?SELECT ji.[iID] AS ID
FROM et_d_JobInfo ji,et_s_Comp c
WHERE ji.iCompID = c.[iID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND ji.[iID]
NOT IN (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
ORDER BY ID DESC
not in 也改
把模糊查询条件放在最后(?)
exists是对外表做loop循环,然后每次loop循环再对内部进行查询如果两个表一个较小一个较大。则子查询大表的用exists,子查询表小的用inexp: A 小表 B 大表
1.SELECT * FROM A WHERE CC IN (SELECT CC FROM B)
效率低,用到了A上的CC列索引
SELECT * FROM A WHERE EXISTS (SELECT CC FROM B WHERE CC = A.CC)
效率高,用到了B表上的CC列索引
2.SELECT * FROM B WHERE CC IN (SELECT CC FROM A)
效率高,用到了B表上CC列索引
SELECT * FROM B WHERE EXISTS (SELECT CC FROM A WHERE CC = B.CC)
效率低,用到了A表上CC列的索引
not in 是对内外表进行全表扫描,没有用到索引
not exists的子查询仍用表上索引
所以不论什么情况。not exists比not in要快
例子你就看上面的写吧
IN 是用主表的索引
EXISTS是用子表的索引主表小的时候用IN,子表小的时候用EXISTS不论什么情况,只用NOT EXISTS,不用NOT IN
FROM et_d_JobInfo ji,et_s_Comp c
WHERE ji.iCompID = c.[iID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND
NOT Exists (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
And ji.[iID]=[iJobID]
)
ORDER BY ID DESC
SELECT ji.[iID] AS ID
FROM et_d_JobInfo ji RIGHT JOIN et_s_Comp c
ON ji.iCompID = c.[iID]
WHERE ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%'))
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%'))
AND (c.iIndustryID LIKE '%%')
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND
NOT EXISTS (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
And ji.[iID]=[iJobID]
)
--ORDER BY ID DESC21秒
SELECT ji.[iID] AS ID FROM et_d_JobInfo AS ji
LEFT JOIN et_s_Comp AS c ON ji.iCompID = c.[iID]
WHERE ji.iCompID = c.[iID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND
NOT Exists (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
And ji.[iID]=[iJobID]
)
ORDER BY ID DESC你用的是全联结。笛卡尔积,不慢才怪
NOT EXISTS (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
And ji.[iID]=[iJobID]
)
这段不执行,看看执行时间如何
是不是ps_d_ResumeRec表的数据量也很大?
SELECT ji.[iID] AS ID
FROM et_s_Comp c LEFT JOIN et_d_JobInfo ji
ON ji.iCompID = c.[iID]
WHERE ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%'))
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%'))
AND (c.iIndustryID LIKE '%%')
AND iSalaryID = 13 AND tiJobTerm = 1 AND tijobstate = 1
--AND
--NOT EXISTS (
-- SELECT [iJobID]
-- FROM [ps_d_ResumeRec]
-- WHERE [iUserID] = 395007
---- AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
-- And ji.[iID] = [iJobID]
--)
--ORDER BY ID DESC23秒 SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 70秒
SELECT ji.[iID] AS ID
FROM et_s_Comp c LEFT JOIN et_d_JobInfo ji
ON ji.iCompID = c.[iID] 用时10秒,数据量是60万条
查询的瓶颈应该是在like那一段。数据量太大了,like效率不行
http://community.csdn.net/Expert/topic/3295/3295983.xml?temp=.8689844
use mydatabase
select * from table1 where username like'%c%"
以下是完成上面功能的另一种写法:use mydatabase
select * from table1 where charindex('c',username)>0
这种方法理论上比上一种方法多了一个判断语句,即>0, 但这个判断过程是最快的, 我相信80%以上的运算都是花在查找字符串及其它的运算上, 所以运用charindex函数也没什么大不了。用这种方法也有好处, 那就是对%,|等在不能直接用like 查找到的字符中可以直接在这charindex中运用, 如下:
use mydatabase
select * from table1 where charindex('%',username)>0
大家还可以写成:
use mydatabase
select * from table1 where charindex(char(37),username)>0
ASCII的字符即为%
注意,应该是这2个字段的联合索引
而不是2个字段上建单独的索引
类似ji.iWorkPlaceID1 LIKE '33%',改为left(ji.iWorkPlaceID1,2)='33'试试
SELECT [iJobID] into #tb
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7SELECT ji.[iID] AS ID
FROM et_d_JobInfo ji,et_s_Comp c,#tb d
WHERE ji.iCompID = c.[iID] and ji.[iID]=d.[iJobID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1 and d.[iJobID] is null
ORDER BY ID DESC
drop table #tb
--修改
--iWorkPlaceID1,iWorkPlaceID2,iWorkPlaceID3建立索引
SELECT [iJobID] into #tb
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7SELECT ji.[iID] AS ID
FROM et_d_JobInfo ji
inner join et_s_Comp c on ji.iCompID = c.[iID]
left join #tb d on ji.[iID]=d.[iJobID]
WHERE ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%'))---这个啥意思。。
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1 and d.[iJobID] is null
ORDER BY ID DESC
drop table #tb
尽量不要用or用sqlserver的执行计划找出瓶颈,创建索引
SELECT ji.[iID] AS ID FROM et_d_JobInfo AS ji
LEFT JOIN et_s_Comp AS c ON ji.iCompID = c.[iID]
WHERE ji.iCompID = c.[iID]
AND ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%') )
AND ((ji.iWorkPlaceID1 LIKE '33%'
OR ji.iWorkPlaceID2 LIKE '33%'
OR ji.iWorkPlaceID3 LIKE '33%') )
AND (c.iIndustryID LIKE '%%' )
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND
NOT Exists (
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
--AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7
AND [dtAddTime]<getdate()-7
And ji.[iID]=[iJobID]
)
ORDER BY ID DESC
--这样试下
2.把那些给力的筛选条件尽量放在后面
3.像 like '%%' 和 like '%xx' 的这种去掉好了 like 'xx%'可以保留
4. NOT EXISTS 和 not in 像你这个数据量的话 这2个差别应该是不大的 ,数据量再大一点的话 还是用not in好
5.表的顺序是对的 大表放前面
6.你这个需求想一句话要达到5秒基本上不可能
FROM
(SELECT ji.[iID] AS ID, ji.iFunTypeID1, ji.iFunTypeID2, ji.iWorkPlaceID1, ji.iWorkPlaceID2, ji.iWorkPlaceID3
FROM et_d_JobInfo ji,et_s_Comp c
WHERE ji.iCompID = c.[iID]
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
) AS jii
WHERE (jii.iFunTypeID1 LIKE '%%' OR jii.iFunTypeID2 LIKE '%%')
AND ((jii.iWorkPlaceID1 LIKE '33%'
OR jii.iWorkPlaceID2 LIKE '33%'
OR jii.iWorkPlaceID3 LIKE '33%'))
AND NOT EXISTS
(
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND jii.ID = [iJobID]
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
ORDER BY ID DESC;
FROM
(SELECT ji.[iID] AS ID, iFunTypeID1 , iFunTypeID2, iWorkPlaceID1,iWorkPlaceID2, iWorkPlaceID3
FROM et_d_JobInfo ji,et_s_Comp c
WHERE ji.iCompID = c.[iID]
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
) AS jii
WHERE (jii.iFunTypeID1 LIKE '%%' OR jii.iFunTypeID2 LIKE '%%')
AND ((jii.iWorkPlaceID1 LIKE '33%'
OR jii.iWorkPlaceID2 LIKE '33%'
OR jii.iWorkPlaceID3 LIKE '33%'))
AND NOT EXISTS
(
SELECT [iJobID]
FROM [ps_d_ResumeRec]
WHERE [iUserID] = 395007
AND jii.ID = [iJobID]
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
ORDER BY ID DESC;
FROM
(
SELECT DISTINCT ji.iCompID,ji.[iID]
FROM et_d_JobInfo ji
WHERE ((ji.iFunTypeID1 LIKE '%%' OR ji.iFunTypeID2 LIKE '%%'))
AND((ji.iWorkPlaceID1 LIKE '33%' OR ji.iWorkPlaceID2 LIKE '33%' OR ji.iWorkPlaceID3 LIKE '33%'))
AND ji.iSalaryID = 13
AND ji.tiJobTerm = 1
AND ji.tijobstate = 1
AND NOT EXISTS(SELECT 1 FROM [ps_d_ResumeRec] C WHERE C.[iJobID]=ji.[iID] AND [iUserID] = 395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
)A
JOIN
(
SELECT c.[iID]
FROM et_s_Comp c
WHERE (c.iIndustryID LIKE '%%' )
)B ON A.iCompID=B.[iID]--PLEASE HAVE A TRY
CREATE INDEX IDX0_ET_S_COMP ON ET_S_COMP(iID);STEP 2:SELECT
A.iID
FROM et_d_JobInfo A
INNER JOIN
(
SELECT
iID
FROM et_s_Comp B1
WHERE iIndustryID LIKE '%%'--没看懂你这是LIKE 什么呢?是所有值吗,小弟才学疏浅,没这么写过
AND NOT EXISTS(
SELECT
1
FROM ps_d_ResumeRec B2 --此表数据量大吗,大的话可以考虑iJobID建索引
WHERE iUserID=395007
AND DATEDIFF(D,[dtAddTime],GETDATE()) < 7)
AND B1.iID=B2.iJobID
)
)B
ON A. iCompID=B.iID
WHERE
AND A.iSalaryID = 13
AND A.tiJobTerm = 1
AND A.tijobstate = 1
AND (A.iFunTypeID1 LIKE '%%' OR A.iFunTypeID2 LIKE '%%') --同上
AND (A.iWorkPlaceID1 LIKE '33%' OR A.iWorkPlaceID2 LIKE '33%' OR A.iWorkPlaceID3 LIKE '33%')
ORDER BY A.iID DESC
相信你有了必要的索引
1、显示执行计划,
2、在执行计划中找tablescan,如果有,则在相应的列上建立索引,indexscan的速度比tablescan快得多
3、如果是indexscan看看能不能变成indexseek,这又是质的飞跃
4、由于优化是由存储引擎来完成的,也许变动条件的顺序能够将计划解释的更为完美
我觉得很多人都误解了“优化”,其实影响性能的最根本因素是业务以及针对业务不合理的表结构设计。换句话说:我们总是做亡羊补牢的事情。有些时候是可以弥补的,有些时候我们只能抽根烟郁闷一下而已。