Действительно ли рекурсия хороша в SQL Server?

table_open_cache=1024000

НЕТ! Это таблиц , а не байтов . Измените его на 2000.

key_buffer_size=2147483648

Если вы используете InnoDB, а не MyISAM:

key_buffer_size = 50M
innodb_buffer_pool_size is fine at 96G (for 128GB of RAM)

Это почти бесполезно, измените на 5:

long_query_time=100

И ... [ 1116]

# Thread Specific Values
sort_buffer_size=2147483648
read_buffer_size=2147483648
read_rnd_buffer_size=1073741824
join_buffer_size=1073741824
bulk_insert_buffer_size=4294967296
tmp_table_size=17179869184
max_heap_table_size=8589934592

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

innodb_flush_method = unbuffered

В руководстве говорится:

unbuffered: ... используется для внутреннего тестирования производительности и в настоящее время не поддерживается. Используйте на свой страх и риск.

innodb_random_read_ahead = 1

Из руководства:

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

Итог: отменить все ваши изменения конфигурации , кроме buffer_pool.

9
задан Ben Hoffstein 10 October 2008 в 13:21
поделиться

8 ответов

С новым MS SQL 2005 Вы могли использовать WITHключевое слово

Проверьте этот вопрос и особенно этот ответ.

С Oracle Вы могли использовать CONNECT BY ключевое слово для генерации иерархических запросов (синтаксис).

AFAIK с MySQL необходимо будет использовать рекурсию.

Кроме того, Вы могли всегда создавать таблицу кэша для своего родителя записей-> дочерние отношения

5
ответ дан 4 December 2019 в 21:13
поделиться

Как общий ответ, возможно сделать некоторый довольно сложный материал в SQL Server, которому обычно нужна рекурсия, просто при помощи итеративного алгоритма. Мне удалось выполнить, синтаксический анализатор XHTML Проводит SQL, который работал удивительно хорошо. Код prettifier, который я записал, был сделан в хранимой процедуре. Это не изящно, это скорее похоже на буйвола наблюдения, делающего Балет. но это работает.

2
ответ дан 4 December 2019 в 21:13
поделиться

Вы используете SQL 2005?

Раз так можно использовать Общие Выражения Таблицы для этого. Что-то вдоль этих строк:

;
with CTE (Some, Columns, ItemId, ParentId) as 
(
    select Some, Columns, ItemId, ParentId
    from myTable 
    where ItemId = @itemID
    union all
    select a.Some, a.Columns, a.ItemId, a.ParentId
    from myTable as a
    inner join CTE as b on a.ParentId = b.ItemId
    where a.ItemId <> b.ItemId
)
select * from CTE
1
ответ дан 4 December 2019 в 21:13
поделиться

Проблема, с которой Вы столкнетесь с рекурсией и производительностью, состоит в том, сколько раз она должна будет рекурсивно вызвать для возврата результатов. Каждый рекурсивный вызов является другим отдельным вызовом, к которому нужно будет присоединиться в общие результаты.

В SQL 2k5 можно использовать общее выражение таблицы для обработки этой рекурсии:

WITH Managers AS 
( 
--initialization 
SELECT EmployeeID, LastName, ReportsTo  
FROM Employees 
WHERE ReportsTo IS NULL 
UNION ALL 
--recursive execution 
SELECT e.employeeID,e.LastName, e.ReportsTo 
FROM Employees e INNER JOIN Managers m  
ON e.ReportsTo = m.employeeID 
) 
SELECT * FROM Managers  

или другое решение состоит в том, чтобы сгладить иерархию в другую таблицу

Employee_Managers
ManagerId (PK, FK к Списку сотрудников)
EmployeeId (PK, FK к Списку сотрудников)

Все родительские дочерние отношения были бы сохранены в этой таблице, поэтому если бы менеджер 1 справляется, менеджер 2 управляет сотрудником 3, таблица была бы похожа:

ManagerId EmployeeId
1         2
1         3
2         1

Это позволяет иерархии быть легко запрошенной:

select * from employee_managers em 
inner join employee e on e.employeeid = em.employeeid and em.managerid = 42

Который возвратил бы всех сотрудников, которые имеют менеджера 42. Позитивный аспект будет большей производительностью, но оборотная сторона будет поддержанием иерархии

1
ответ дан 4 December 2019 в 21:13
поделиться

Возможно, еще некоторая деталь в порядке.

Если у Вас будут отношения основной детали, как Вы описываете, то разве, простое СОЕДИНЕНИЕ не получит то, в чем Вы нуждаетесь?

Как в:

SELECT
  SOME_FIELDS
FROM
  MASTER_TABLE MT
 ,CHILD_TABLE CT
WHERE CT.PARENT_ID = MT.ITEM_ID
0
ответ дан 4 December 2019 в 21:13
поделиться

Вам не нужна рекурсия вообще.... Отметьте, я изменил столбцы на ItemID и ItemParentID для простоты ввода...

DECLARE @intLevel INT
SET @intLevel = 1

INSERT INTO TempTable(ItemID, ItemParentID, Level) SELECT ItemID, ItemParentID, @intLevel WHERE ItemParentID IS NULL

WHILE @intLevel < @TargetLevel BEGIN SET @intLevel = @intLevel + 1 INSERT INTO TempTable(ItemID, ItemParentID, Level) SELECt ItemID, ItemParentID, @intLevel WHERE ItemParentID IN (SELECT ItemID FROM TempTable WHERE Level = @intLevel-1) -- If no rows are inserted then there are no children IF @@ROWCOUNT = 0 BREAK END

SELECt ItemID FROM TempTable WHERE Level = @TargetLevel

0
ответ дан 4 December 2019 в 21:13
поделиться

Вам не должна быть нужна рекурсия для детей - Вы только смотрите на уровень непосредственно ниже (т.е. select * from T where ParentId = @parent) - Вам только нужна рекурсия для всех потомков.

В SQL2005 можно получить потомков с:

with AllDescendants (ItemId, ItemText) as (
    select t.ItemId, t.ItemText 
        from [TableName] t
    where t.ItemId = @ancestorId
    union
    select sub.ItemId, sub.ItemText 
        from [TableName] sub
            inner join [TableName] tree
            on tree.ItemId = sub.ParentItemId
)
0
ответ дан 4 December 2019 в 21:13
поделиться

У Joe Celko есть книга (<-связываются с Amazon), конкретно на древовидных структурах в базах данных SQL. В то время как Вам была бы нужна рекурсия для Вашей модели и определенно будет потенциал для проблем производительности там, существуют альтернативные способы смоделировать древовидную структуру в зависимости от того, что включает Ваша определенная проблема, который мог избежать рекурсии и дать лучшую производительность.

1
ответ дан 4 December 2019 в 21:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: