SQL Server 2005: какой из них быстрее? Условие более 2 столбцов или более 2 строк? - PullRequest
1 голос
/ 10 февраля 2010
Table1
------------
ID
IdColumn1
Idcolumn2

Table2
------------
ID
IdColumn
IdPair

Оба они содержат одинаковые данные.

В столбце Table1 оба столбца заполнены, в столбце Table2 эти столбцы хранятся в двух строках.

Таким образом, если Table1 содержит n строк, Table2будет иметь 2 * n строк

Какой запрос будет быстрее?

select * from Table1 
where IdColumn1 = x or IdColumn2 = x

или

select * from Table2 where IdColumn = x

Я уже выбрал схему Table2, и до сих пор у меня более 400.000 строк иболее 1000 уникальных посетителей в день.Каждый день добавляется более 2000 строк в этой базе данных.Мой сайт продолжает расти очень быстро.

Не спрашивайте меня, почему столько строк, они играют в игры в онлайн-соревнованиях, и эти ряды являются матчами между игроками.

Ответы [ 5 ]

2 голосов
/ 10 февраля 2010

Я бы тоже пошел с Таблицей 2.

Чтобы подчеркнуть разницу в подходах, вот 3 плана выполнения, сгенерированных для опций, при условии, что Table1 имеет некластеризованные индексы для IdColumn1 и IdColumn2, а Table2 имеет некластеризованный индекс для IdColumn. ID КЛАСТЕР. 100 000 записей в таблице 1, 200 000 записей в таблице 2

1) Подход Table1 с условием OR для двух столбцов id:
альтернативный текст http://img52.imageshack.us/img52/3264/23430147.png

2) Подход Table1 с двумя операторами в сочетании с UNION ALL:
альтернативный текст http://img192.imageshack.us/img192/6281/47968640.png

3) Подход Table2:
альтернативный текст http://img52.imageshack.us/img52/2131/72286216.png

План Table2, очевидно, намного проще.

1 голос
/ 10 февраля 2010

В таблице 2 реализована модель Entity-Attribute-Value (EAV), которая часто выбирается из-за некоторых преимуществ, которые эта модель предлагает по сравнению с традиционной моделью таблицы (и реляционной моделью). на свободе). Одним из известных преимуществ EAV является то, что поиск OR на основе значений нескольких столбцов эффективен и проще в кодировании, чем в традиционной модели.

Также несколько новых функций, предлагаемых более новыми реализациями SQL-сервера, помогают с моделью EAV.

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

Конечно, последнее слово о том, какая из двух моделей более эффективна [в ограничительном контексте проблемы значения столбца OR-ed], зависит от эффективной реализации, индексов и статистического профиля данных. Для небольших таблиц EAV (например, этой с приблизительно 500 000 записей) модель EAV, вероятно, предлагает преимущество, в общем случае .

См. Соответствующую статью SO: база данных: преимущества, недостатки и альтернативы EAV и вообще просканируйте несколько статей SO с тегом eav .

1 голос
/ 10 февраля 2010

Я бы выбрал Таблица2.

Для схемы Table1 вам нужно как минимум два индекса, один для IdColumn1 и один для IdColumn2, и вы можете эффективно запросить его, используя:

select * from Table1 where IdColumn1 = x
union all 
select * from Table1 where IdColumn2 = x;

Но по крайней мере один из индексов не является кластеризованным, и у вас будет много логических манипуляций для идентификации всех элементов, связанных с игроком, поскольку они могут быть либо в IdColumn1, либо в IdColumn2. И просто подумайте, что в будущем принесет игра с тремя путями (3 игрока, добавьте IdColumn3 ...).

Таблица 2 лучше, так как имеет четкую цель: хранит все игры, в которых принимал участие игрок, сгруппированные по идентификатору игрока. Его можно объединить более просто, его можно структурировать проще и впоследствии можно расширить для большего числа игроков в каждой игре.

Не уверен, что такое PairId. Ваша модель данных является типичным отношением «многие ко многим», просто замените «Player» на «Student» и «Game» на «Course», и вы увидите, что у вас есть точно каноническая структура курса «Моделирование данных 101» для Student-Course. (в вашем случае бывает так, что в игре (= курс) может быть ровно 2 игрока (= студенты), но это мелочь. Вы по-прежнему говорите о типичных отношениях за 3 столами (1 для игр, 1 для игроков, один для участия игрока в игре).

0 голосов
/ 10 февраля 2010

Единственная причина, по которой одна таблица быстрее, чем другая, - это то, какие индексы вы создаете для таблиц. В случае второй таблицы нет никакого преимущества в производительности, если только вы не создадите правильные индексы для первой таблицы (или наоборот).

Например, может показаться, что вторая таблица быстрее, потому что вы создали индекс для idcolumn1 в таблице 1 и idcolumn для таблицы 2. Если вместо этого вы создали индекс для idcolumn1 и другой индекс для idcolumn2 в таблице 1, то вы бы увидеть очень похожую производительность.

Поскольку таблица 2 является дублированием данных, не рекомендуется вести эту таблицу. Каждое обновление требует изменения двух строк.

Тем не менее, я вижу конструкции данных для этого типа данных, которые выглядят так:

match table
-----------
matchid
additional match information

participants table
------------------
participantid
matchid

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

Тогда вам просто нужно выбрать участников и связать их с данными матча.

Я считаю, что это будет наилучшей практикой для вашей ситуации.

0 голосов
/ 10 февраля 2010

Сложно сказать.Я думаю, что оба должны иметь одинаковую производительность или, может быть, второе должно быть лучше, поскольку idColumn является первичным ключом.Проверьте план выполнения запроса и убедитесь, что у меня правильные индексы.

...