#sql-server #tsql
Вопрос:
Как я могу оптимизировать запрос. Я просмотрел план выполнения и создал весь индекс. Каждая таблица содержит огромные данные. И это время выполнения запроса очень велико. Посмотрев на запрос, не могли бы вы, пожалуйста, подсказать, где я могу оптимизировать больше.
Если я приведу небольшую предысторию запроса, структура будет выглядеть так:
- Существует множество компаний
- В каждой компании может быть несколько менеджеров
- Данные представлены в формате разбиения на страницы
- Фильтр на #parent_manager, поэтому другая временная таблица создала parent_manager_filter только для использования в целях фильтрации, поскольку #parent_manager имеет имя в формате»,», разделенном
CREATE TABLE #parent_manager
(
cid NUMERIC(18) PRIMARY KEY,
name NVARCHAR(MAX),
code NVARCHAR(MAX)
);
CREATE INDEX cte_parent_manager ON #parent_manager(cid);
CREATE TABLE #parent_manager_filter
(
cid NUMERIC(18),
name NVARCHAR(1000),
code NVARCHAR(1000)
);
CREATE INDEX cte_parent_manager_filter_idx ON #parent_manager_filter(cid);
INSERT INTO #parent_manager
SELECT DISTINCT
mgrc.cid,
name = CAST (STUFF ((SELECT ', ' CAST(c.company_name AS varchar(2000))
FROM manager_company mc
INNER JOIN company c ON (mc.mgr_cid = c.cid )
WHERE mc.cid = mgrc.cid
AND c.company_name IS NOT NULL
FOR XML PATH ('')), 1, 1, '') AS VARCHAR(2000)),
code = CAST (STUFF ((SELECT ', ' CAST(c.code AS varchar(2000))
FROM manager_company mc
INNER JOIN company c ON (mc.mgr_cid = c.cid )
WHERE mc.cid = mgrc.cid
AND c.company_name IS NOT NULL
FOR XML PATH ('')), 1, 1, '') AS VARCHAR(2000))
FROM
manager_company mgrc
INNER JOIN
company c ON (mgrc.mgr_cid = c.cid )
JOIN
handler h ON (c.handlerId = h.handlerid )
WHERE
h.handlerid = 5800657002370
INSERT INTO #parent_manager_filter
SELECT DISTINCT
mc.cid,
c.company_name as name,
c.code as code
FROM
manager_company mc
INNER JOIN
company c ON (mc.mgr_cid = c.cid )
JOIN
handler h ON (h.handlerid = c.handlerid)
WHERE
h.handlerid = 5800657002370 ;
WITH company AS
(
SELECT DISTINCT
c.cid AS cid,
parentManager.name AS MANAGER_NAME,
parentManager.code AS code
FROM
company c
LEFT JOIN
#parent_manager parentManager ON (parentManager.cid = c.cid)
LEFT JOIN
# parent_manager_filter parentManagerFilter ON (parentManagerFilter.cid = c.cid)
WHERE
parentManagerFilter.name IN (:managerList)
),
total_rows AS
(
SELECT
COUNT(*) OVER () AS TOTALCOUNT,
ROW_NUMBER() OVER (ORDER BY company_name ASC) AS rnum,
grid.*
FROM
company grid
)
SELECT *
FROM total_rows rnum
WHERE rnum >= 1
AND rnum <= 10
DROP TABLE #parent_manager;
DROP TABLE #parent_manager_filter;
Комментарии:
1. Я бы рекомендовал использовать лучшие измерения, чем «огромные данные» и «время выполнения очень велико» или «большая компания», потому что это настолько неясно, что никто не будет знать, с чего начать. Укажите точные измерения, продолжительность, структуры таблиц и индексирования, а также план запроса.
2. Почему вы заявляете
varchar(max)
, какие у вас данныеvarchar(2000)
, и я бы задался вопросом, нужно ли вам это тожеnumeric(18)
— так что этоbigint
тогда? Тебе это нужно ? Используйте соответствующие типы данных — для миллионов строк это определенно поможет.3. Пожалуйста, смотрите раздел вставка плана , чтобы узнать, как включить план выполнения в свой вопрос. Где находится DDL
handler
и его индекс(индексы)?
Ответ №1:
Если вы создаете временные таблицы, я бы убедился, что вы не пропустите кластеризованный индекс, иначе ваша временная таблица-это просто куча. У вас нет такого, который покрывал бы таблицу фильтров.
INSERT INTO #parent_manager_filter ...
CREATE CLUSTERED INDEX cte_parent_manager_filter On #parent_manager_filter(cid);
Комментарии:
1. Да, индекс был создан, пропустив эту часть.
2. @Techie321 Улучшилась ли скорость запроса?
3. Это уже было там, я пропустил, чтобы упомянуть об этом здесь.
4. Вы пробовали вынимать подзапросы внутри выборок (в основном материалы)? Сокращает ли это время запроса?
5. Кроме того, почему вы этим занимаетесь, вы можете захотеть создать некластеризованный индекс для #parent_manager.code и #parent_manager_filter.code. Это может повредить чему угодно, и вы можете сравнить планы запросов.