#c_sharp #sql_server #entity_framework_core
Есть некоторая таблица в базе SQL Server 2008 R2:
Три столбца, три индекса.
Создана она при помощи Entity Framework, всё просто:
public class Order
{
public int Id { get; set; }
public int GroupBuyingId { get; set; }
public GroupBuying GroupBuying { get; set; }
public int ParticipantId { get; set; }
public Contact Participant { get; set; }
}
Через какое-то время прилетело требование наложить ограничение уникальности на поля
GroupBuyingId и ParticipantId, ну я и сделал:
public class OrderConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
builder.HasIndex(x => new { x.GroupBuyingId, x.ParticipantId }).IsUnique();
}
}
Но перед тем как применять миграцию - автоматически глянул, что там создано:
public partial class UniqueConstraintForOrder : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Orders_GroupBuyingId",
table: "Orders");
migrationBuilder.CreateIndex(
name: "IX_Orders_GroupBuyingId_ParticipantId",
table: "Orders",
columns: new[] { "GroupBuyingId", "ParticipantId" },
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropIndex(
name: "IX_Orders_GroupBuyingId_ParticipantId",
table: "Orders");
migrationBuilder.CreateIndex(
name: "IX_Orders_GroupBuyingId",
table: "Orders",
column: "GroupBuyingId");
}
}
И вот что мне непонятно. Создаётся новый индекс по двум полям - это правильно. Но
зачем-то сносится один из существующих индексов (кстати, почему не оба?), видимо из
расчёта, что можно будет использовать составной?
Что вообще в подобных случаях рекомендуется делать - оставлять один составной индекс
или составной + два отдельных?
Понятно, что во втором случае объём занимаемый индексом будет больше, плюс соответственно
время на его обработку при вставке новых значений, а что насчёт скорости выборок?
Будет ли составной индекс работать так же эффективно, как и одиночные?
Ответы
Ответ 1
Разница для составного индекса и индекса с одним полем заключается в длине ключа, чем длиннее ключ, тем больше операций чтения при поиске для большой таблицы придется выполнить движку. В приведенном примере нет смысла держать дубль индекса, так как разница в длине ключа несущественна, практического выигрыша по чтениям не будет. Поиск всегда использует первое поле ключа индекса, поэтому второй индекс не удаляется, так как он построен по другому (не по первому в составном) полю.Ответ 2
Составной индекс по полям (A, B) всегда может использоваться вместо индекса (A), но не может использоваться вместо индекса (B). Ну, если это стандартный B-Tree индекс. Тем не менее, поиск по простому индексу (A) будет чуть быстрее, чем по составному (A, B), из-за бо́льшего числа записей в одном ключевом узле дерева. Но на интах вы этого не заметите.
Комментариев нет:
Отправить комментарий