Еще один подход для длинных запросов SQL - PullRequest
0 голосов
/ 10 октября 2011

У меня есть запрос, целью которого является получение записей в соответствии с параметрами поиска. Другие параметры в порядке, но есть одно поле с именем «Член». Когда пользователи помещают часть имени в это текстовое поле «Участник», оно должно возвращать все записи, в которых этот «Участник» был задействован в различных ролях. У меня был довольно сложный запрос, но он был в порядке, и потребовалась секунда, прежде чем было указано предложение where. Мое предыдущее предложение where было похоже на

WHERE (( C.IDNumber LIKE '%11%' AND  C.OriginalIDNumber LIKE '%11%' 
AND  H.UserDisplayName  LIKE '%david%' OR C.SubmittedBy LIKE '%david%' 
OR J.UserID IN( Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR L.UserID IN( Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR X.DepartmentHead IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR E.DepartmentHead IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR N.UserID IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR O.UserID IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR Y.OrganisationAdmin IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR Y.FinalApprovalAuthority IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR Y.OrganisationFinance IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%') 
OR Z.UserID IN (Select UserID from USER_PROFILE where UserDisplayName LIKE '%david%'))) 
AND (C.Status<>'Draft')

J, L, X, E и т. Д. - это разные таблицы, к которым я должен присоединиться. Мне потребовалось больше минуты, и я изменил его в

WHERE (( C.IDNumber LIKE '%11%' AND  C.OriginalIDNumber LIKE '%11%' 
AND  H.UserDisplayName  LIKE '%david%' OR C.SubmittedBy LIKE '%david%' OR W.UserDisplayName LIKE '%david%' 
OR AA.UserDisplayName LIKE '%david%' OR BB.UserDisplayName LIKE  '%david%' OR CC.UserDisplayName LIKE  '%david%' 
OR DD.UserDisplayName LIKE  '%david%' OR EE.UserDisplayName LIKE  '%david%' OR FF.UserDisplayName LIKE  '%david%' 
OR GG.UserDisplayName LIKE  '%david%' OR HH.UserDisplayName LIKE  '%david%' OR II.UserDisplayName LIKE  '%david%')) 
AND (C.Status<>'Draft')

путем помещения левого внешнего соединения для таблицы User_Profile с J, L, X, E и так далее. AA, BB, CC и т. Д. - это новые таблицы User_Profile, которые нужно объединить.

Но это все еще занимает 30 секунд, что приводит к ошибке «Timeout Expired», когда я запускаю приложение. Любой другой подход, чтобы сократить время, затрачиваемое на запрос?

Я использую MSSQL 2008.

Ответы [ 3 ]

1 голос
/ 10 октября 2011

Какая версия MS SQL?Начиная с 2005 года вы можете использовать CTE (общие табличные выражения) - сначала вы выбираете все возможные идентификаторы в CTE, а затем присоединяетесь к нему.

1 голос
/ 10 октября 2011

Вы можете использовать CTE, чтобы избежать дублирования кода:

WITH IdWeLikeToCheck AS
( Select UserID 
  from USER_PROFILE 
   where UserDisplayName LIKE '%david%'
)

....
WHERE ( ( C.IDNumber LIKE '%11%' AND  C.OriginalIDNumber LIKE '%11%' 
AND  H.UserDisplayName LIKE '%david%' OR C.SubmittedBy LIKE '%david%' 

OR J.UserID IN IdWeLikeToCheck 
OR L.UserID IN IdWeLikeToCheck 
OR X.DepartmentHead IN IdWeLikeToCheck  
OR E.DepartmentHead IN IdWeLikeToCheck  
... 
OR Z.UserID IN IdWeLikeToCheck )) 
AND (C.Status<>'Draft')

Чтобы кто-то посмотрел на ошибку тайм-аута, вам нужно будет предоставить полный запрос, определения таблиц иплан выполнения.

0 голосов
/ 10 октября 2011

Пока у вас есть запросы с подстановочными знаками "% xxx%" в конце (на самом деле спереди, сзади хорошо), ваши индексы будут игнорироваться для этих таблиц. Любой подстановочный знак в начале не может быть разрешен с помощью индекса.

И поля типа IDNumber, надеюсь, действительно являются числами, поэтому подстановочные знаки не имеют особого смысла; и сравнение значения числового поля со строкой (или наоборот) также приведет к неправильному использованию индексов.

Я полагаю, что, следовательно, он читает каждую запись в каждой таблице в запросе, иногда более одного раза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...