sql >> Databáze >  >> RDS >> Sqlserver

Zlepšete výkon dotazů SQL Server na velkých tabulkách

Jednoduchá odpověď:NE. Nemůžete si pomoci s ad hoc dotazy na 238sloupcovou tabulku s 50% faktorem vyplnění v seskupeném indexu.

Podrobná odpověď:

Jak jsem uvedl v jiných odpovědích na toto téma, návrh indexu je umění i věda a existuje tolik faktorů, které je třeba vzít v úvahu, že existuje jen málo, pokud vůbec nějaká, tvrdých a rychlých pravidel. Musíte vzít v úvahu:objem operací DML vs. SELECTy, diskový subsystém, další indexy/spouštěče v tabulce, distribuci dat v tabulce, jsou dotazy používající podmínky SARGable WHERE a několik dalších věcí, které si ani nepamatuji správně nyní.

Mohu říci, že s otázkami na toto téma nelze poskytnout žádnou pomoc bez pochopení samotné tabulky, jejích indexů, spouštěčů atd. Nyní, když jste zveřejnili definici tabulky (stále čekáte na indexy, ale samotná definice tabulky ukazuje na 99 % problému) Mohu nabídnout nějaké návrhy.

Za prvé, pokud je definice tabulky přesná (238 sloupců, 50% faktor vyplnění), pak můžete zbytek odpovědí / rad zde v podstatě ignorovat;-). Omlouvám se, že jsem tu méně než politický, ale vážně, je to divoká honička, aniž bychom znali podrobnosti. A nyní, když vidíme definici tabulky, je o něco jasnější, proč by jednoduchý dotaz trval tak dlouho, i když testovací dotazy (aktualizace č. 1) běžely tak rychle.

Hlavním problémem zde (a v mnoha situacích se špatným výkonem) je špatné datové modelování. 238 sloupců není zakázáno, stejně jako není zakázáno mít 999 indexů, ale obecně to také není příliš moudré.

Doporučení:

  1. Nejprve tento stůl opravdu potřebuje předělat. Pokud se jedná o tabulku datového skladu, pak možná, ale pokud ne, pak je skutečně nutné tato pole rozdělit do několika tabulek, které mohou mít všechny stejné PK. Měli byste hlavní tabulku záznamů a podřízené tabulky jsou pouze závislé informace založené na běžně přidružených atributech a PK těchto tabulek je stejná jako PK hlavní tabulky a tedy také FK k hlavní tabulce. Mezi hlavní a všemi podřízenými tabulkami bude vztah 1:1.
  2. Použití ANSI_PADDING OFF je znepokojující, nemluvě o nekonzistentnosti v tabulce kvůli různým přidáváním sloupců v průběhu času. Nejste si jisti, zda to nyní můžete opravit, ale v ideálním případě byste vždy měli ANSI_PADDING ON , nebo alespoň mít stejné nastavení ve všech ALTER TABLE prohlášení.
  3. Zvažte vytvoření 2 dalších skupin souborů:tabulky a indexy. Nejlepší je nevkládat své věci do PRIMARY protože to je místo, kde SQL SERVER ukládá všechna svá data a metadata o vašich objektech. Vytvoříte svou tabulku a seskupený index (což jsou data pro tabulku) na [Tabulky] a všechny indexy bez klastrů na [Indexy]
  4. Zvyšte faktor plnění z 50 %. Toto nízké číslo je pravděpodobně důvodem, proč je váš indexový prostor větší než datový prostor. Při opětovném sestavení indexu se znovu vytvoří datové stránky s maximální velikostí 4 kB (z celkové velikosti stránky 8 kB) použitých pro vaše data, takže tabulka bude rozprostřena na velkou plochu.
  5. Pokud většina nebo všechny dotazy obsahují „ER101_ORG_CODE“ v WHERE podmínku, pak zvažte její přesunutí do úvodního sloupce seskupeného indexu. Za předpokladu, že se používá častěji než "ER101_ORD_NBR". Pokud se "ER101_ORD_NBR" používá častěji, ponechte si jej. Jen se zdá, že za předpokladu, že názvy polí znamenají „OrganizationCode“ a „OrderNumber“, že „OrgCode“ je lepší seskupení, které může mít více „OrderNumbers“ v sobě.
  6. Drobný bod, ale pokud má „ER101_ORG_CODE“ vždy 2 znaky, použijte CHAR(2) místo VARCHAR(2) protože ušetří bajt v záhlaví řádku, který sleduje různé velikosti šířky a sčítá miliony řádků.
  7. Jak již uvedli ostatní, pomocí SELECT * poškodí výkon. Nejen kvůli tomu, že vyžaduje, aby SQL Server vrátil všechny sloupce, a tudíž s větší pravděpodobností provedl Clustered Index Scan bez ohledu na vaše ostatní indexy, ale také trvá SQL Serveru čas, než přejde k definici tabulky a přeloží * do všech názvů sloupců. Mělo by to být mírně rychleji specifikovat všech 238 názvů sloupců v SELECT seznam to však nepomůže s problémem skenování. Ale opravdu někdy potřebujete všech 238 sloupců současně?

Hodně štěstí!

AKTUALIZACE
Pro úplnost otázky „jak zlepšit výkon na velké tabulce pro ad-hoc dotazy“ je třeba poznamenat, že i když to v tomto konkrétním případě nepomůže, POKUD někdo používá SQL Server 2012 (nebo novější, až ten čas přijde) a POKUD se tabulka neaktualizuje, je možné použít indexy Columnstore. Další podrobnosti o této nové funkci najdete zde:http://msdn.microsoft.com/en-us/library/gg492088.aspx (Domnívám se, že byly vytvořeny tak, aby bylo možné je aktualizovat od SQL Server 2014).

AKTUALIZACE 2
Další aspekty:

  • Povolte kompresi na clusterovém indexu. Tato možnost byla dostupná v SQL Server 2008, ale pouze jako funkce Enterprise Edition. Nicméně od SQL Server 2016 SP1 , Komprese dat byla zpřístupněna ve všech edicích! Podrobnosti o kompresi řádků a stránek naleznete na stránce MSDN pro kompresi dat.
  • Pokud nemůžete použít kompresi dat nebo pokud to pro konkrétní tabulku nepřinese mnoho výhod, pak POKUD máte sloupec typu s pevnou délkou (INT , VELKÝ , TINYINT , SMALLINT , CHAR , NCHAR , BINÁRNÍ , DATETIME , SMALLDATETIME , MONEY , atd.) a více než 50 % řádků je NULL , pak zvažte povolení SPARSE možnost, která se stala dostupnou v SQL Server 2008. Podrobnosti naleznete na stránce MSDN pro použití řídkých sloupců.


  1. Funkce pro odstranění akcentů v postgreSQL

  2. MariaDB JSON_OBJECT() Vysvětleno

  3. ERD notace v datovém modelování

  4. Filtrovat podle COUNT(*)?