SQL-запрос выбора занимает много времени с предложением WHERE - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть одна таблица Table1, которая содержит 1 - 1,5 миллиона строк с первичным ключом.

Это моя структура таблицы

CREATE TABLE [dbo].[Table1]
(
    [Id] [INT] NOT NULL,    
    [allow_public] [BIT] NULL,
    [average_frequency] [DECIMAL](18, 4) NULL,
    [category_id] [INT] NULL,
    -- a few more columns
    --
    --
    --
    [member_id] [INT] NULL

    CONSTRAINT [PK_Table1_Id] 
        PRIMARY KEY CLUSTERED ([Id] ASC)
)

Добавлен некластеризованный индекс для member_id, например:

CREATE NONCLUSTERED INDEX non_cluster_index_member_table1
    ON dbo.Table1 (member_id) 
    WHERE member_id IS NOT NULL;
    GO

Когда я выполняю запрос, как

SELECT
    [id], 
    [accurate_grams],
    [allow_public],
    [average_frequency],
    [category_id]
FROM
    dbo.Table1 
WHERE 
    member_id = @memberid;

возвращает несколько строк в течение миллисекунд.Но когда я выполняю запрос, такой как

SET @OrgMemberId = ISNULL(@OrgMemberId, -1);

SELECT
    [id], 
    [accurate_grams],
    [allow_public],
    [average_frequency],
    [category_id]
FROM 
    dbo.Table1 f
WHERE 
    ISNULL(f.member_id, -1) = CASE 
                                 WHEN @MemberId = -1 
                                    THEN ISNULL(f.member_id, -1) 
                                    ELSE @MemberId 
                              END

, для завершения выполнения требуется много времени.

Примечание. : member_id столбец содержит нулевые значения.И он не отображается в качестве внешнего ключа

    ISNULL(f.member_id, -1) = CASE 
                                 WHEN @MemberId = -1 
                                    THEN ISNULL(f.member_id, -1) 
                                    ELSE @MemberId 
                              END

Причина написания выше строки такова - иногда пользователи отправляют нулевое значение на @MemberId.Чтобы справиться с этим сценарием, я использовал эту строку в предложении where.В одном запросе я могу получить два разных результата.При запросе member_id is null выберите все записи, а при запросе member_id is not null выберите только те записи, которые совпадают с Member_id.Таким образом, нет необходимости использовать if else.

Есть ли какое-либо другое решение для этого?

1 Ответ

0 голосов
/ 27 декабря 2018

Один из возможных подходов - использовать , охватывающий индекс - индекс, который содержит все столбцы, которые ваш запрос должен вернуть:

CREATE NONCLUSTERED INDEX ncix_table1_member_id
ON dbo.Table1 (member_id) 
INCLUDE (id, accurate_grams, allow_public, average_frequency, category_id)
WHERE member_id IS NOT NULL;
GO

С этимподход, теперь ваш запрос может быть «удовлетворен», просто посмотрев на индекс - и он не должен делать много (довольно дорогих) «ключевых поисков» на страницах данных фактической таблицы, чтобы извлечь «отсутствующие» значения столбцапо вашему запросу

...