Является ли этот план выполнения мотивацией для переосмысления моих первичных ключей? - PullRequest
1 голос
/ 12 мая 2009

Когда я вошел в свою текущую (работодатель) компанию, была разработана новая схема базы данных, которая будет основой многих будущих инструментов, которые будут / будут создаваться. С моим ограниченным знанием SQL я думаю, что таблица довольно хорошо разработана. Меня беспокоит только то, что почти каждая таблица имеет первичный ключ, состоящий из нескольких частей. У каждой таблицы есть как минимум CustomerId и собственный ключ. Хотя они действительно являются определяющими для определенной записи, у меня есть ощущение, что несколько клавиш (здесь мы говорим о четверке) очень неэффективны.

Сегодня я наблюдал невообразимое использование ЦП над простым повторяющимся запросом, который объединяет две таблицы, выбирает одно строковое поле из первой и отличает их.

select distinct(f.FIELDNAME) as fieldName
from foo f
inner join bar b
   on f.id = b.fId
where b.cId = @id;

Проверка плана выполнения (я не герой EP) Я заметил, что есть три основных момента процессора. Отличный (как и ожидалось) и два стремятся к индейцам. Лично я считаю, что поиск индексов должен быть очень быстрым, но они занимают 18% от стоимости каждого. Это нормально? Это связано с (четырехкратными) кластерными индексами?

- ОБНОВЛЕНИЕ -
Запрос используется для создания индекса Lucene. Это однократная обработка, которая происходит примерно еженедельно (я знаю, это звучит противоречиво). Я не могу повторно использовать результаты здесь, насколько я вижу.

Ответы [ 3 ]

3 голосов
/ 12 мая 2009

Не могли бы вы выполнить следующие запросы и опубликовать их вывод:

SELECT  COUNT(*), COUNT(DISTINCT fieldname)
FROM    foo

SELECT  COUNT(*), COUNT(DISTINCT cId), COUNT(DISTINCT fId)
FROM    bar

Это поможет оценить, какие индексы лучше всего соответствуют вашим потребностям.

Тем временем убедитесь, что у вас есть следующие индексы:

foo (FIELDNAME)
bar (cId, fId)

и перепишите ваш запрос:

SELECT  DISTINCT(fieldname)
FROM    foo f
WHERE   EXISTS (
        SELECT  1
        FROM    bar b
        WHERE   b.fId = f.id
                AND b.cId = @id
        )

Этот запрос должен использовать индекс на f.FIELDNAME для построения списка DISTINCT и индекс на bar для фильтрации несуществующих значений.

1 голос
/ 12 мая 2009

Этот вид запроса выглядит знакомо. Я предполагаю здесь, но, вероятно, он заполняет поле со списком на веб-интерфейсе / интерфейсе winform, который довольно сильно ударил.

Возможно, вам следует кэшировать результаты на стороне приложения, чтобы не выполнять его так часто. В худшем случае вы можете кешировать это на стороне серверов sql, но это огромный шаг вперед.

0 голосов
/ 12 мая 2009

В большинстве баз данных индексы не используются, если первый столбец в индексе отсутствует в списке. Вы говорите, что customerId является частью каждого первичного ключа, но вы не используете его для объединения в вашем запросе. Чтобы правильно ответить на ваш вопрос, нам действительно нужно увидеть вывод create table для foo и bar или, по крайней мере, show index from.

Тем не менее, ваш запрос может быть быстрее, если вы измените его следующим образом:

select distinct(f.FIELDNAME) as fieldName
from foo f
inner join bar b
   on f.id = b.fId
   and f.cId = b.cId #Using this part of the key will speed it up
where b.cId = @id;

Мой комментарий предполагает, что ваш первичный ключ упорядочен как "cId, fId". Это означает, что ваш запрос не должен проверять каждый cId, а только те, которые являются частью индекса.

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