Если вы можете изменить кластеризованные индексы coupledrecords
и notcoupledrecords
, чтобы они содержали один столбец из smalltable (включая привязку вычисляемого битового столбца в конце каждого кластеризованного индекса, исключительно для этой цели - см. Ответ @Martin Smith выше), тогда вы можете использовать Partitioned View для вставки. Это простая возможность.
Если это невозможно, вы также можете попробовать решение без разделов. Смотрите ниже - это более запутанно.
Не зная, как распределяются ваши данные (например, размер строки, число столбцов, которые можно обнулять или не обнулять, отношение связанных и не связанных), трудно порекомендовать общее решение, но одно решение, которое может работать хорошо в большинстве случаев, это использовать представления для имитации связанных и несвязанных таблиц поверх одной таблицы "maybecoupled
". Использование представлений означает, что ваш существующий код запроса (кроме вставки) не нужно будет менять.
На первый взгляд это кажется неэффективным, но помните, что нулевые значения занимают нулевое пространство памяти, и при правильных индексах SQL не будет тратить много времени на фильтрацию строк "другого представления".
Вот как это будет работать:
- INSERT все записей в базовой таблице (например,
maybecoupled
) за один проход
- Убедитесь, что в одном из столбцов, полученных из
smalltable
, есть индекс (в идеале, кластеризованный, но и некластеризованный). Давайте предположим, что это indexedcol1
- Создайте два представления сверху:
coupledrecords
и notcoupledrecords
, определения которых SELECT col1, ... FROM maybecoupled WHERE indexedcol1 IS NULL
и SELECT col1, ... FROM maybecoupled WHERE indexedcol1 IS NOT NULL
.
- если у вас есть кластеризованный индекс для indexedcol1, то вы будете платить минимальные или нулевые штрафы за большинство запросов, поскольку каждый запрос в любом представлении будет попадать только в соответствующую половину записей и никогда не затрагивать другую половину. Ваши некластеризованные индексы станут немного больше и, следовательно, немного медленнее, но даже это можно улучшить с помощью отфильтрованных индексов .
- если вы не можете использовать кластеризованный индекс, убедитесь, что indexcol1 является частью (или INCLUDE-d в) каждого некластеризованного индекса. Это предотвращает необходимость возврата к кластерному индексу для поиска indexcol1 для запросов, которые извлекают данные только из некластеризованных индексов.
Вот несколько случаев, когда вышеуказанное решение не будет работать:
- , если число связанных строк относительно невелико и у вас либо много необнуляемых столбцов в
bigtable
, либо у вас очень маленькие строки. Тогда пространство над всеми этими несвязанными рядами может пострадать. (пустые значения не занимают места, но столбцы, не имеющие значения NULL).
- если вы используете некластеризованный indexcol1 и не можете изменить ваши индексы, чтобы обеспечить наличие indexcol1 в ваших некластеризованных индексах
- если вышеуказанные махинации приводят к тому, что SQL Server выбирает неправильные индексы для использования в планах запросов из-за повышенной сложности запросов (хотя это можно исправить с помощью подсказок по индексам)
Предостережение: вы определенно захотите протестировать производительность любого солютона на основе представлений, чтобы убедиться, что он не ухудшает ситуацию - SQL обычно хорош при выборе хороших планов запросов, но не всегда. Тест, Тест, Тест!