Хорошо у нас есть простой udf, который берет целочисленный список XML и возвращает таблицу:
CREATE FUNCTION [dbo].[udfParseXmlListOfInt]
(
@ItemListXml XML (dbo.xsdListOfInteger)
)
RETURNS TABLE
AS
RETURN
( --- parses the XML and returns it as an int table ---
SELECT ListItems.ID.value('.','INT') AS KeyValue
FROM @ItemListXml.nodes('//list/item') AS ListItems(ID)
)
В хранимой процедуре мы составляем временную таблицу с помощью этого UDF
INSERT INTO @JobTable
(JobNumber, JobSchedID, JobBatID, StoreID, CustID, CustDivID, BatchStartDate, BatchEndDate, UnavailableFrom)
SELECT JOB.JobNumber,
JOB.JobSchedID,
ISNULL(JOB.JobBatID,0),
STO.StoreID,
STO.CustID,
ISNULL(STO.CustDivID,0),
AVL.StartDate,
AVL.EndDate,
ISNULL(AVL.StartDate, DATEADD(day, -8, GETDATE()))
FROM dbo.udfParseXmlListOfInt(@JobNumberList) TMP
INNER JOIN dbo.JobSchedule JOB ON (JOB.JobNumber = TMP.KeyValue)
INNER JOIN dbo.Store STO ON (STO.StoreID = JOB.StoreID)
INNER JOIN dbo.JobSchedEvent EVT ON (EVT.JobSchedID = JOB.JobSchedID AND EVT.IsPrimary = 1)
LEFT OUTER JOIN dbo.Availability AVL ON (AVL.AvailTypID = 5 AND AVL.RowID = JOB.JobBatID)
ORDER BY JOB.JobSchedID;
Для простого списка 10 JobNumbers в SQL2005 это возвращается меньше чем через 1 секунду, в 2008 это выполнение против тех же самых возвратов данных в 7 минут. Это находится на намного более быстрой машине с большей памятью. Какие-либо идеи?
Если я изменяю SP, чтобы сделать это вместо этого, производительность становится сопоставимой с версией 2005 года.
DECLARE @JobNumbers TABLE
(
JobNumber INT NOT NULL
);
INSERT INTO @JobNumbers
(JobNumber)
SELECT * from dbo.udfParseXmlListOfInt(@JobNumberList);
INSERT INTO @JobTable
(JobNumber, JobSchedID, JobBatID, StoreID, CustID, CustDivID, BatchStartDate, BatchEndDate, UnavailableFrom)
SELECT JOB.JobNumber,
JOB.JobSchedID,
ISNULL(JOB.JobBatID,0),
STO.StoreID,
STO.CustID,
ISNULL(STO.CustDivID,0),
AVL.StartDate,
AVL.EndDate,
ISNULL(AVL.StartDate, DATEADD(day, -8, GETDATE()))
FROM @JobNumbers TMP
INNER JOIN dbo.JobSchedule JOB ON (JOB.JobNumber = TMP.JobNumber)
INNER JOIN dbo.Store STO ON (STO.StoreID = JOB.StoreID)
INNER JOIN dbo.JobSchedEvent EVT ON (EVT.JobSchedID = JOB.JobSchedID AND EVT.IsPrimary = 1)
LEFT OUTER JOIN dbo.Availability AVL ON (AVL.AvailTypID = 5 AND AVL.RowID = JOB.JobBatID)
ORDER BY JOB.JobSchedID;
Убедитесь, что у серверов одинаковые индексы.
Также проверьте актуальность статистики:
SELECT
object_name = Object_Name(ind.object_id),
IndexName = ind.name,
StatisticsDate = STATS_DATE(ind.object_id, ind.index_id)
FROM SYS.INDEXES ind
order by STATS_DATE(ind.object_id, ind.index_id) desc
Для получения дополнительной помощи опубликуйте разницу между планами выполнения запроса ( установите showplan_text на
)