2016-06-03 1 views
2

Ищет входы по следующему запросу, в котором используется переменная таблицы, получающая результаты фамилии с соответствующими идентификаторами CustomerNumberID.Последнее Поиск по сайту Поиск Улучшение производительности SQL

1.

INSERT INTO #MatchingIndividuals (CustomerNumberID) 
    SELECT DISTINCT(c.CustomerNumberID) 
    FROM CustomerNumber c 
    WHERE c.CustomerTypeID = 1 
     AND EXISTS (
      SELECT 1 
      FROM CustomerIndividualNameSearch cn 
       INNER JOIN CustomerIndividualName cin 
        ON cn.CustomerIndividualNameID = cin.CustomerIndividualNameID 
       CROSS JOIN #NameCriteria cnc 
      WHERE cin.CustomerNumberID = c.CustomerNumberID 
       AND cn.LastName LIKE cnc.LastName ESCAPE @escape) 
    ORDER BY c.CustomerNumberID 
    OFFSET @SKIP ROWS FETCH NEXT @ROWS ROWS ONLY 

2. #NameCriteria объявлен как

SELECT LastName, FirstName, MiddleName 
     FROM dbo.CustomerIndividualNameCriteriaExpansion(@LastName, @FirstName, @MiddleName, @ExactSearch, @LastNameThreshold, @escape)' 

      SET @where = @where + ' 
     AND EXISTS (
      SELECT 1 
      FROM #NameCriteria cnc 
       INNER JOIN CustomerIndividualNameSearch cn 
        ON ' + @namewhere + ' 
       INNER JOIN CustomerIndividualName cin 
        ON cn.CustomerIndividualNameID = cin.CustomerIndividualNameID 
      WHERE cin.CustomerNumberID = c.CustomerNumberID)' 

3.CustomerIndividualNameCriteriaExpansion это инлайн таблица функция, которая расширяет первый, средний и фамилию для поиска по шаблону имен.

Запрос возвращается в течение 30 секунд или более для возврата. Предложения?

+0

Давайте просто скажем, что 'CROSS JOIN #NameCriteria cnc ' выглядит подозрительно, как причина. Вы понимаете, каков эффект производительности CROSS JOIN? –

+0

В зависимости от менеджера db крест-соединение может быть преобразовано в внутреннее соединение планировщиком. Так что это запах кода, но не обязательно проблема производительности. Однако для обеспечения производительности укажите, какие RDBMS вы используете, и соответствующим образом помечайте вопрос, поскольку настройка производительности часто является специфичной для РСУБД. –

+0

Добавлены теги 'sql-server' и' tsql' на основе кода в вопросе –

ответ

0

# Таблицы имеют тенденцию быть довольно медленными - вместо этого используйте common table expression.

WITH NameCriteria (LastName, FirstName, MiddleName) 
as 
(
    SELECT LastName, FirstName, MiddleName 
    FROM dbo.CustomerIndividualNameCriteriaExpansion(@LastName, @FirstName, @MiddleName, @ExactSearch, @LastNameThreshold, @escape)' 
) 

SELECT DISTINCT(c.CustomerNumberID) 
FROM CustomerNumber c 
WHERE c.CustomerTypeID = 1 
    AND EXISTS (
     SELECT TOP 1 1 
     FROM CustomerIndividualNameSearch cn 
      INNER JOIN CustomerIndividualName cin 
       ON cn.CustomerIndividualNameID = cin.CustomerIndividualNameID 
      CROSS JOIN NameCriteria cnc 
     WHERE cin.CustomerNumberID = c.CustomerNumberID 
      AND cn.LastName LIKE cnc.LastName ESCAPE @escape) 
ORDER BY c.CustomerNumberID 
OFFSET @SKIP ROWS FETCH NEXT @ROWS ROWS ONLY 

Далее я хотел бы посмотреть на CROSS JOIN заявлении - вы хотите сравнить каждую запись вы должны каждый критерий имен, но это может привести к массовому числу записей, идущим в свой LIKE заявления.

Microsoft SQL лучше при оптимизации LIKE с индексами, если шаблон начинается с текстом, так 'something%' быстрее, чем '%something' - это будет зависеть от того, какого CustomerIndividualNameCriteriaExpansion возвращается.

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