2013-12-17 2 views
0

У меня есть TSQL-код, который опирается на хранимую процедуру для выбора строки.Удар производительности с множеством результатов Набор из одной строки

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

Мой первый вопрос: есть ли беспокойство или выступления близки к тому, что я получил бы с одним набором результатов x строк?

Второй вопрос: кто-нибудь думает, что временная таблица, в которой моя хранимая процедура вставляет результат (вместо выбора), должна быть быстрее?

Редактировать: В основном эта хранимая процедура выбирает все элементы данного иерархического объекта.

ALTER PROCEDURE [dbo].[MtdMdl_HierarchicalObject_Collection_Items] 
@relatedid int 

AS 
BEGIN 
    SET NOCOUNT ON 

    declare @curkeyid int 
    declare cur CURSOR static read_only LOCAL 
     for select distinct [Id] from MtdMdl_Item where [Owner] = @relatedid 

    open cur 
    fetch next 

    from cur into @curkeyid 
    while @@FETCH_STATUS = 0 
    BEGIN 

     -- select the item row from its ID 
     exec MtdMdl_Item_ItemBase_Read @keyid = @curkeyid 

     fetch next 
     from cur into @curkeyid 
    END 
    close cur 
    deallocate cur 
END 

ALTER PROCEDURE [dbo].[MtdMdl_Item_ItemBase_Read] 
@keyid int 
AS 
BEGIN 
    SET NOCOUNT ON 

    SELECT TOP(1) [Id], [TimeStamp], [Name], [Owner], [Value] 
    FROM [MtdMdl_Item] 
    WHERE ([Id][email protected]) 
    ORDER BY TimeStamp Desc 
END 
+1

Можете ли вы показать запросы у вас есть вопросы? –

ответ

2
  1. Для того, чтобы выбрать окончательный набор записей, вы должны поместить все отдельные строки вывода в итоговую временную таблицу. В вашем коде нет причин возвращать один рекурсор, содержащий все отдельные строки из итерации над курсором с помощью sp;
  2. Ваш MtdMdl_Item_ItemBase_Read имеет значение немного, потому что после его включения в функцию вы можете избежать курсора sp + и выполнить задачу одним запросом с помощью встроенной функции.

обн
Согласно вашей структуре данных, я понимаю, что ваш [Id] не является единственным, который является источником запутанным.
Есть много способов сделать то, что вам нужно, но вот пример одного запроса, даже избегая КТР для временного результата:

DECLARE @relatedid int = 2 

SELECT top(1) WITH ties 
[Id], [TimeStamp], [Name], [Owner], [Value] 
FROM MtdMdl_Item 
WHERE [Owner][email protected] 
ORDER BY row_number() over(partition BY [Id] ORDER BY [TimeStamp] DESC) 

Рассмотрим SQL Fiddle как демо.

UPD2

Примера с функцией рядных таблиц:

CREATE FUNCTION MtdMdl_Item_ItemBase_Read (@keyid int) 
RETURNS TABLE 
AS 
RETURN 
(
    SELECT TOP(1) [Id], [TimeStamp], [Name], [Owner], [Value] 
    FROM [MtdMdl_Item] 
    WHERE ([Id][email protected]) 
    ORDER BY TimeStamp Desc 
) 
GO 

DECLARE @relatedid int = 2 

SELECT DISTINCT A.[Id],B.* FROM MtdMdl_Item A 
OUTER apply (SELECT * FROM MtdMdl_Item_ItemBase_Read(A.[Id])) B 
WHERE A.[Owner] = @relatedid 

SQL Fiddle 2

+0

Это интересно, хорошо, я поставлю код второго SP.Спасибо – Nock

+0

Просто убедитесь, что нет никакой вставки/обновления внутри sp или вызова других sp; – revoua

+0

Я не знаком с функцией, можете ли вы поместить образец, который избавится от курсора + sp, пожалуйста? – Nock

0

Ваш ответ в ссылке ниже, вы должны использовать GROUP BY вместо DISTINCT

SQL/mysql - Select distinct/UNIQUE but return all columns?

А ниже строки кода войти в список столбцов вы хотите в вашем результате

declare cur CURSOR static read_only LOCAL 
     for select distinct [Id] from MtdMdl_Item where [Owner] = @relatedid 

Таким образом, ваш запрос будет

declare cur CURSOR static read_only LOCAL 
     for select rows,you,want,in,result from MtdMdl_Item where [Owner] = @relatedid Order By [column name you want to be distinct] 
Смежные вопросы