Подтвердить что ты не робот

Должны ли таблицы MultiTenant включать TenantID в первичные и внешние ключи?

Для многопользовательской единой общей базы данных необходимо, чтобы поле tenantid было включено в первичный ключ и кластеризованный индекс? Или добавляет дополнительный индекс на tenantid так же, как и исполнитель?

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

Все операторы SELECT SELECT начинаются с tenantid в своих выражениях с объектами, такими как

invoiceitems.tenantid = thecurrenttenantid order by invoicedate

ТЕКУЩАЯ СХЕМА

Арендаторы (первичный ключ tenantid uniqueidentifier, tenantname) Внешние ключи (tenantid) Индексы (Clustered on tenantid)

Клиенты (tenantid uniqueidentifier, первичный ключ customerid uniqueidentifier, имя пользователя varchar (50)) Внешние ключи (tenantid, customerid) Индексы (кластеризованные на customerid)

Счета-фактуры (tenantid uniqueidentifier, первичный ключ уникального идентификатора invoiceid, уникальный идентификатор клиента, уникальный идентификатор клиента, дата-дата и время его выставления) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (сгруппированы по invoiceid)

InvoiceItems (tenantid uniqueidentifier, invoiceitemid uniqueidentifier primarykey, invoiceid uniqueidentifier, lineitemorder int) Иностранные ключи (tenantid, invoiceid) Индексы (сгруппированы по invoiceitemid)

SqlAzure требует, чтобы каждая таблица имела кластеризованный индекс, так что в настоящее время он находится только на primarykeyid, поскольку это значение по умолчанию. Сейчас это единственный индекс для каждой таблицы. Существуют различные внешние ключи в таблицах по всей системе, и ни одно из полей таблицы внешнего ключа не индексируется.

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

Все операторы SELECT SELECT начинаются с tenantid в своих выражениях с помощью операторов linq.

invoiceitems.tenantid = thecurrenttenantid order by invoicedate

Некоторые операторы select sql просто имеют порядок - некоторые из них имеют другие значения условия соединения при введении дочерних таблиц, например

invoiceitems.tenantid = thecurrenttenantid and invoice.invoiceid = invoiceitems.invoiceid order by invoicedate

Вот несколько идей (мы открыты для других, кроме этого) - , какой из них был бы лучшим и почему?

ВАРИАНТЫ УКАЗАТЕЛЯ ПЕРВИЧНОГО КЛЮЧА

Чтобы ускорить доступ к записям арендатора

Вариант 1 - добавьте некластеризованный индекс в tenantid

Счета-фактуры (tenantid uniqueidentifier, первичный ключ invoiceid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (сгруппированные по invoiceid, не кластеризованные на tenantid)

Вариант 2 - Измените первичный ключ от primaryid до tenantid + primaryid и измените кластеризованный индекс на tenantid + primaryid.

Счета-фактуры ( первичный ключ tenantid uniqueidentifier, первичный ключ invidentid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (кластеризованные на tenantid + invoiceid)

ВАРИАНТЫ УКАЗАТЕЛЕЙ ВНЕШНЕГО КЛЮЧА

Чтобы ускорить соединение

Вариант 3 - добавьте некластеризованные индексы во все поля внешнего ключа только на foreignkeyid.

Счета-фактуры (tenantid uniqueidentifier, первичный ключ invoiceid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (сгруппированные по invoiceid, некластеризованные на billcustomerid, некластеризованные на shipcustomerid)

Вариант 4 - Измените все внешние ключи от foreignkeyid до tenantid + foreignkeyid и добавьте индекс на tenantid + foreignkeyid

Счета-фактуры (tenantid uniqueidentifier, первичный ключ invoiceid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, tenantid + billcustomerid, tenantid + shipcustomerid) Индексы (сгруппированные по invoiceid, некластеризованные на tenantid + billcustomerid, не кластерные на tenantid + shipcustomerid)

SQL SELECT OPTIMIZATION INDEX OPTIONS

Чтобы ускорить часто используемые запросы, такие как выбор полей из счетов-фактур, где tenantid = порядок значений invoicedate

Вариант 5 - добавьте индексы для наиболее часто используемых полей порядка сортировки в каждой таблице, кроме tenantid.

Счета-фактуры (tenantid uniqueidentifier, первичный ключ invoiceid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (сгруппированные по invoiceid, не кластеризованные на invoicedate)

Вариант 6 - добавьте индексы на tenantid + "наиболее часто используемое поле порядка сортировки" в каждой таблице и добавьте некластеризованный индекс в tenantid + "наиболее часто используемое поле порядка сортировки"

Счета-фактуры (tenantid uniqueidentifier, первичный ключ invoiceid uniqueidentifier, уникальный идентификатор клиента, уникальный идентификатор shipcustomerid, invoicedate datetime) Иностранные ключи (tenantid, billcustomerid, shipcustomerid) Индексы (сгруппированные по invoiceid, не кластеризованные на tenantid + invoicedate)

4b9b3361

Ответ 1

Похоже, вы много размышляли. Независимо от того, что я или кто-то еще говорит, единственный способ узнать наверняка - это измерить его самостоятельно. В этом случае это становится меньше вопроса SQL Azure и более общего вопроса оптимизации запросов SQL Server.

Для вас есть несколько советов, которые помогут вам начать работу. Поскольку вы используете LINQ, у вас нет прямого доступа к фактическим запросам, которые запускаются в SQL. Вы можете подумать, что знаете, как должен выглядеть запрос, но в зависимости от того, какую версию EF вы используете, он может принять некоторые интересные решения о том, как структурировать запрос. Чтобы выяснить, какие именно запросы выполняются, вам понадобится использовать SQL Profiler. К сожалению, SQL Profiler не работает с SQL Azure, поэтому вы захотите получить копию своей БД на локальном сервере и запустить приложение, указывая на локальное. экспортный уровень уровня данных и связанный импорт в SQL Server Management Studio (SSMS) очень полезны для этого.

С помощью реальных запросов вы можете запустить их в SSMS для базы данных в Azure, чтобы получить план выполнения. Затем вы можете внести изменения в свои индексы, снова запустить запрос и сравнить планы. Если вы не хотите связываться со своей основной БД разработки, вы можете легко создать копию с помощью CREATE DATABASE xxx КАК КОПИРОВАТЬ yyyy.

Не пытайтесь делать оптимизацию в локальной БД. SQL Azure имеет другую структуру производительности, чем большинство при установке SQL.

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

Наконец, не беспокойтесь об использовании указаний для своих ПК, если ваша БД становится достаточно большой, чтобы вам нужно было объединить ее с помощью идентификатора арендатора (который, по-видимому, похож на вашу структуру), столбцы IDENTITY перестают быть опцией.

Ответ 2

Я согласен с ответом от @knigtpfhor, но добавлю, что если вы собираетесь использовать федерации в SQL Azure, вам нужно будет включить ключ федерации (TenantID) как часть кластерного индекса для каждой таблицы в члене федерации, (Ваш вариант № 2 выше). Подробнее см. Правила и ограничения для федерации.

Я бы добавил в свои таблицы дополнительные некластеризованные индексы; выбор полей для индексирования - это немного науки и немного искусства, но я обычно стараюсь начать с рассмотрения запросов, которые я, вероятно, выпущу, и убедиться, что у меня есть индекс, который охватывает соответствующие поля. Моя догадка заключается в том, что, хотя ваши первичные\внешние ключи индексируются, они, вероятно, не коррелируют во всех случаях с тем, как вы действительно запрашиваете данные.

Какие проблемы с производительностью вы испытываете? У вас проблемы с записью данных или запросами данных или обоими? Насколько велика эта база данных? Являются ли ваши проблемы с производительностью прерывистыми или довольно последовательными?