Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Въпрос относно производителността на SQL Server HierarchyID в дълбочина

Не е съвсем ясно дали се опитвате да оптимизирате за търсене в дълбочина или в ширина; въпросът предполага първо в дълбочина, но коментарите в края са за първо в ширина.

Имате всички индекси, от които се нуждаете за първо в дълбочина (просто индексирайте hierarchyid колона). За широчината на първо място не е достатъчно само да творите изчисленото level колона, трябва да я индексирате също:

ALTER TABLE Message
ADD [Level] AS MessageID.GetLevel()

CREATE INDEX IX_Message_BreadthFirst
ON Message (Level, MessageID)
INCLUDE (...)

(Имайте предвид, че за неклъстерирани индекси най-вероятно ще имате нужда от INCLUDE - в противен случай SQL Server може вместо това да прибегне до сканиране на клъстерен индекс.)

Сега, ако се опитвате да намерите всички предци на възел, искате да вземете малко по-различен подход. Можете да направите тези търсения светкавично бързи, защото - и ето какво е страхотно в hierarchyid - всеки възел вече "съдържа" всички свои предци.

Използвам CLR функция, за да направя това възможно най-бързо, но можете да го направите с рекурсивен CTE:

CREATE FUNCTION dbo.GetAncestors
(
    @h hierarchyid
)
RETURNS TABLE
AS RETURN
WITH Hierarchy_CTE AS
(
    SELECT @h AS id

    UNION ALL

    SELECT h.id.GetAncestor(1)
    FROM Hierarchy_CTE h
    WHERE h.id <> hierarchyid::GetRoot()
)
SELECT id FROM Hierarchy_CTE

Сега, за да получите всички предшественици и потомци, използвайте го по следния начин:

DECLARE @MessageID hierarchyID   /* passed in from application */

SELECT m.MessageID, m.MessageComment 
FROM Message as m
WHERE m.MessageId.IsDescendantOf(@MessageID) = 1
OR m.MessageId IN (SELECT id FROM dbo.GetAncestors(@MessageID.GetAncestor(1)))
ORDER BY m.MessageID

Опитайте - това трябва да реши проблемите ви с производителността.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. sql ос с динамични колони

  2. Предаване на масив към съхранена процедура на SQL Server

  3. Скрити характеристики на SQL Server

  4. Използване на Excel VBA за изпълнение на SQL заявка

  5. Ще върне ли GETUTCDATE() една и съща стойност, ако се използва два пъти в едно и също изявление?