Selektiver Index von 1C – was wählt MS SQL? / Sudo Null IT-Nachrichten

Wer ist er – selektiver Index

Im vorherigen Artikel Partitionierte Programmiererdisziplin in 1C wurde ein Beispiel für eine Abfrage zum Verbinden zweier Tabellen für das Informationsregister gezeigt, und es wurde gezeigt, wie MS SQL Datenströme für Merge-Joins mithilfe von Standard-1C-Indizes auswählt. Insbesondere wurde darauf hingewiesen, dass ohne zusätzliche Bedingungen in der Indexsuche alle Indexdatensätze in den Stream für Megre Join gelangen und Sie zusätzliche Filter zur Einschränkung angeben müssen. Frage: Warum passiert das? – offen geblieben.

Alles, was im Folgenden beschrieben wird, ist meine Schlussfolgerung basierend auf der Analyse des Verhaltens des MS SQL 2019-Optimierers unter verschiedenen Bedingungen. Ich habe keine offiziell angegebenen Algorithmen gefunden, die der MS SQL-Optimierer verwendet. Wenn Sie den Link kennen, schreiben Sie ihn in die Kommentare.

Erinnern wir uns zunächst an den Begriff eines selektiven Index.

Kurz gesagt, ein Index für eine bestimmte Abfrage ist selektiv, wenn Sie bei seiner Verwendung auswählen können

  • Mehr eindeutige Zeilen

  • Mit weniger Takes

  • Wenigste Zeilen pro Schlüsselwertkombination

Über Selektivität ist hier gut geschrieben (gilt für Oracle, aber dies ist ein allgemeines Konzept)

selektiver Index

Nehmen wir die optimierte Abfrage aus dem vorherigen Artikel

Wählen Sie verschiedene suu_gogenensions.Ein gebundenes ampidschystem wie verbunden mit Ophysiastems, legen Sie den Zeitpunkt der Genesung aus dem Register. ////////////////////////////////////////////////// / ///////////////////////////////////////////////// ////////////// .НогаСделки ПОМЕСТИТЬ РезультатВыбранныеВерсииСделок ИЗ РегистрСведений.СУУ_АгрегированнаяСделкаКП КАК СУУ_АгрегированнаяСделкаКП ВНУТРЕННЕЕ СОЕДИНЕНИЕ Врем_ИдОперацийИзТранзакций КАК Врем_ИдОперацийИзТранзакций ПО СУУ_АгрегированнаяСделкаКП.ИдИсхСистемы = Врем_ИдОперацийИзТранзакций.СвязаннаяОпИдИсхСистемы ГДЕ СУУ_АгрегированнаяСделкаКП.Период >= ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, – 3) //И опять его запустим со стандартными индексами 1С. MS SQL нас интересует последний запрос INSERT INTO #tt3 WITH(TABLOCK) (_Q_001_F_000, _Q_001_F_001RRef, _Q_001_F_002, _Q_001_F_003RRef, _Q_001_F_004RRef) SELECT T1._Period, T1._Fld18861RRef, T1._Fld18865, T1._Fld18863RRef, T1._Fld19363RRef FROM dbo._InfoRg18860 T1 WITH(NOLOCK) INNER JOIN #tt2 T2 WITH(NOLOCK) ON (T1._Fld18865 = T2._Q_000_F_000) WHERE ((T1._Fld628 = @P1)) AND ((T1._Period >= @P2))’,N’ @P1 numerisch(10),@P2 datetime2(3)

Wir betrachten den vom Optimierer festgelegten Gesamtpreis – in Papageien 7767

Der Plan wird mit Index Seek by type index _InfoR18860_ByDims18897_STRRRR abgerufen

Indexstruktur

Der Abfrageplan ist unten, Sie können sehen, dass der Großteil der E/A für Indexsuch- und Zusammenführungsoperationen verwendet wird

Alles scheint in Ordnung zu sein, gemäß den Regeln und vorhersehbar, aber fügen wir einen weiteren Index hinzu, in dem das Feld _Fld628 entfernt wurde. Dieses Feld enthält 0, da es in der typischen Konfiguration vorhanden ist, aber nicht verwendet wird

Sehen wir uns das Ergebnis an. Überraschenderweise hat SQL Server den neuen Index selbst gewählt, obwohl _Fld628 (Trennzeichen) überhaupt nicht vorhanden ist! Obwohl es einen Index _InfoR18860_ByDims18897_STRRRR gibt, der alle Bedingungen formal erfüllt.

Der Plan ging besser auf, aber nicht viel.

Unterschied

1) |–Indexsuche(OBJEKT:([MIS_PROD2].[dbo].[_InfoRg18860].[_InfoR18860_ByDims18897_STRRRR] WIE [T1]), SUCHEN:([T1].[_Fld628]=[@P1]), WO:([MIS_PROD2].[dbo].[_InfoRg18860].[_Period] wie [T1].[_Period]>=[@P2]) VORAUSBESTELLT)

2) Ein Nicht-Standard-Index wird gescannt, wobei alle Bedingungen geprüft sind |–Index Scan(OBJECT:([MIS_PROD2].[dbo].[_InfoRg18860].[_InfoR18860_MySuperWithout_Fld628_ByDims18897_STRRRR] WIE [T1]), WO:([MIS_PROD2].[dbo].[_InfoRg18860].[_Fld628] wie [T1].[_Fld628]=[@P1] UND [MIS_PROD2].[dbo].[_InfoRg18860].[_Period] wie [T1].[_Period]>=[@P2]) VORAUSBESTELLT)

Wir wählen einen selektiven Index und der Optimierer wählt …

Warum hat MS SQL das gemacht? Höchstwahrscheinlich tötet das Feld, in dem _Fld628 = 0 in jedem Datensatz ist, alle Indexselektivität, und sobald eine würdige Alternative zu MS SQL auftaucht, rennt er dorthin

Frage Und an welcher Stelle des Index setzen Sie dann dieses Feld _Fld628 (DataAreaMainData), das 1C standardmäßig an den Anfang (Präfix) aller Indizes setzt?

Dies ist eine schwierige Frage. Wenn DataRegionMainData mit mindestens mehreren Werten verwendet wird, erhöht sich die Selektivität im Standardindex unter Berücksichtigung der Gleichheitsbedingungen, die 1C T1._Fld628 = @P1 hinzufügt (Gleichheit hat immer Vorrang vor >= <= durch den Optimierer)

Aber alles ist sehr abhängig vom DBMS, zum Beispiel werden hier Mythen über selektive Indizes beschrieben und Pläne für verschiedene DBMS

Verwenden Sie den Index-Look

„Der Mythos hält sich in der SQL Server-Umgebung außerordentlich hartnäckig und taucht sogar in der offiziellen Dokumentation auf. Der Grund dafür ist, dass SQL Server nur für die erste Indexspalte ein Histogramm führt. Das bedeutet aber, dass sich die Empfehlung lauten sollte wie „zuerst n gerade verteilte Spalten“, weil Histogramme für gleichmäßig verteilte Spalten ohnehin nicht sehr sinnvoll sind.“

Diese. Die erste Spalte im Index entscheidet über alles und die Anzahl der eindeutigen Werte. Steht dort eine 0, ist die Arbeit mit den restlichen Feldern schon weniger effizient. Wenn 0 1 2, dann verbessert dies die Situation auch nicht wesentlich, da bei Merge ohne zusätzliche Bedingungen der Datenfluss durch T1._Fld628 = @P1 fließt

Im Allgemeinen ist es besser, ohne das DataRegionMainData-Feld zu leben als damit, aber wenn Sie darauf nicht verzichten können, können Sie die Situation nur verbessern, indem Sie alternativ die Abfrage der Plattform selbst erstellen, und dies ist eine weitere alternative Geschichte für die folgende Artikel. Ich freue mich, Sie auf unserem Kanal zu sehen 😊 t.me/Chat1CUnlimited

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *