SQL Server: zapytanie szybkie, ale wolne od procedury

Zapytanie działa szybko:

DECLARE @SessionGUID uniqueidentifier
SET @SessionGUID = 'BCBA333C-B6A1-4155-9833-C495F22EA908'

SELECT *
FROM Report_Opener
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank

Koszt Subtree: 0.502

W 2008 roku firma SQL wprowadziła do swojej oferty nową wersję SQL-A, która w 2009 roku została rozszerzona o nową wersję SQL-a.]}
CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS
SELECT *
FROM Report_Opener
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank

EXECUTE ViewOpener @SessionGUID

Koszt Subtree: 19.2

Uciekłem

sp_recompile ViewOpener

I nadal działa tak samo (źle), zmieniłem też zapisany procedura do

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS
SELECT *, 'recompile please'
FROM Report_Opener
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank

I z powrotem, próbując naprawdę oszukać go do rekompilacji.

Upuściłem i odtworzyłem procedura składowana w celu wygenerowania nowego planu.

Nie jest to jednak żaden problem, ponieważ nie jest to problem, który może być spowodowany błędem.]}
CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier AS

DECLARE @SessionGUIDbitch uniqueidentifier
SET @SessionGUIDbitch = @SessionGUID

SELECT *
FROM Report_Opener
WHERE SessionGUID = @SessionGUIDbitch
ORDER BY CurrencyTypeOrder, Rank

Próbowałem również zdefiniować procedurę składowanąWITH RECOMPILE:

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier 
WITH RECOMPILE
AS
SELECT *
FROM Report_Opener
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank
To, że jego plan nigdy nie jest buforowany, i próbowałem wymusić rekompilację w execute:
EXECUTE ViewOpener @SessionGUID WITH RECOMPILE
Co nie pomogło.

Próbowałem przekonwertować procedurę na dynamiczny SQL:

CREATE PROCEDURE dbo.ViewOpener @SessionGUID uniqueidentifier 
WITH RECOMPILE AS
DECLARE @SQLString NVARCHAR(500)

SET @SQLString = N'SELECT *
   FROM Report_OpenerTest
   WHERE SessionGUID = @SessionGUID
   ORDER BY CurrencyTypeOrder, Rank'

EXECUTE sp_executesql @SQLString,
N'@SessionGUID uniqueidentifier',
@SessionGUID

Które nie pomogło.

Encja "Report_Opener " jest widokiem, który nie jest indeksowany. Widok odwołuje się tylko do bazowych tabel. Żadna tabela nie zawiera obliczonych kolumn, indeksowanych lub innych.

Do diabła z tym próbowałem stworzyć widok z

SET ANSI_NULLS ON
SET QUOTED_IDENTIFER ON
To tego nie naprawiło.

Jak to jest, że

  • zapytanie jest szybkie
  • [[68]} przenoszenie zapytania do widoku i wybieranie z widoku jest szybkie
  • wybieranie z widoku z procedury składowanej jest 40x wolniej?

Próbowałem przenieść definicję widoku bezpośrednio do procedury składowanej (łamanie 3 reguł biznesowych i łamanie ważnej enkapsulacji), co czyni go tylko około 6x wolniejszym.

Dlaczego wersja procedury składowanej jest tak wolna? Co może oznaczać, że serwer SQL działa ad-hoc SQL szybciej niż inny rodzaj ad-hoc SQL?

I ' d really rather not

  • osadzenie SQL w kodzie
  • Zmień kod na wszystkie

    Microsoft SQL Server  2000 - 8.00.2050 (Intel X86)
    Mar  7 2008 21:29:56
    Copyright (c) 1988-2003 Microsoft Corporation
    Standard Edition on Windows NT 5.2 (Build 3790: Service Pack 2)
    

Ale co może wyjaśnić, że SQL Server nie może działać tak szybko, jak SQL Sever uruchamiający zapytanie, jeśli nie sniffing parametrów.


Moją następną próbą będzie wywołanie StoredProcedureA wywołanie StoredProcedureB wywołanie StoredProcedureC wywołanie StoredProcedureD aby odpytywać widok.

I w przeciwnym razie niech procedura składowana wywoła procedurę składowaną, wywoła UDF, wywoła UDF, wywoła procedurę składowaną, wywoła UDF, aby odpytywać widok.


Podsumowując, następujący bieg szybko z QA, ale powolne, gdy zostanie wprowadzone do procedury składowanej:

Oryginał:

--Runs fine outside of a stored procedure
SELECT *
FROM Report_OpenerTest
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank

sp_executesql:

--Runs fine outside of a stored procedure
DECLARE @SQLString NVARCHAR(500)
SET @SQLString = N'SELECT *
FROM Report_OpenerTest
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank'

EXECUTE sp_executesql @SQLString,
        N'@SessionGUID uniqueidentifier',
        @SessionGUID

EXEC(@sql):

--Runs fine outside of a stored procedure
DECLARE @sql NVARCHAR(500)
SET @sql = N'SELECT *
FROM Report_OpenerTest
WHERE SessionGUID = '''+CAST(@SessionGUID AS varchar(50))+'''
ORDER BY CurrencyTypeOrder, Rank'

EXEC(@sql)

Plany Egzekucji

Dobry plan:

      |--Sort(ORDER BY:([Expr1020] ASC, [Currencies].[Rank] ASC))
           |--Compute Scalar(DEFINE:([Expr1020]=If ([Currencies].[CurrencyType]='ctCanadianCash') then 1 else If ([Currencies].[CurrencyType]='ctMiscellaneous') then 2 else If ([Currencies].[CurrencyType]='ctTokens') then 3 else If ([Currencies].[CurrencyType]
                |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Openers].[OpenerGUID]))
                     |--Filter(WHERE:((([Currencies].[IsActive]<>0 AND [Currencies].[OnOpener]<>0) AND ((((((([Currencies].[CurrencyType]='ctUSCoin' OR [Currencies].[CurrencyType]='ctMiscellaneousUS') OR [Currencies].[CurrencyType]='ctUSCash') OR [Currencies].
                     |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Currencies].[CurrencyGUID], [Openers].[OpenerGUID]) WITH PREFETCH)
                     |         |--Nested Loops(Left Outer Join)
                     |         |    |--Bookmark Lookup(BOOKMARK:([Bmk1016]), OBJECT:([GrobManagementSystemLive].[dbo].[Windows]))
                     |         |    |    |--Nested Loops(Inner Join, OUTER REFERENCES:([Openers].[WindowGUID]))
                     |         |    |         |--Bookmark Lookup(BOOKMARK:([Bmk1014]), OBJECT:([GrobManagementSystemLive].[dbo].[Openers]))
                     |         |    |         |    |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_SessionGUID]), SEEK:([Openers].[SessionGUID]=[@SessionGUID]) ORDERED FORWARD)
                     |         |    |         |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Windows].[IX_Windows]), SEEK:([Windows].[WindowGUID]=[Openers].[WindowGUID]) ORDERED FORWARD)
                     |         |    |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))
                     |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID] AND [OpenerDetails].[CurrencyGUID]=[Currenc
                     |--Hash Match(Cache, HASH:([Openers].[OpenerGUID]), RESIDUAL:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]))
                          |--Stream Aggregate(DEFINE:([Expr1006]=SUM(If (((([Currencies].[CurrencyType]='ctMiscellaneous' OR [Currencies].[CurrencyType]='ctTokens') OR [Currencies].[CurrencyType]='ctChips') OR [Currencies].[CurrencyType]='ctCanadianCoin') OR [
                               |--Nested Loops(Inner Join, OUTER REFERENCES:([OpenerDetails].[CurrencyGUID]) WITH PREFETCH)
                                    |--Nested Loops(Inner Join)
                                    |    |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_OneOpenerPerSession]), SEEK:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)
                                    |    |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)
                                    |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[PK_Currencies_CurrencyGUID]), SEEK:([Currencies].[CurrencyGUID]=[OpenerDetails].[CurrencyGUID]) ORDERED FORWARD)

The bad plan

       |--Sort(ORDER BY:([Expr1020] ASC, [Currencies].[Rank] ASC))
            |--Compute Scalar(DEFINE:([Expr1020]=If ([Currencies].[CurrencyType]='ctCanadianCash') then 1 else If ([Currencies].[CurrencyType]='ctMiscellaneous') then 2 else If ([Currencies].[CurrencyType]='ctTokens') then 3 else If ([Currencies].[Currency
                 |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Openers].[OpenerGUID]))
                      |--Filter(WHERE:((([Currencies].[IsActive]<>0 AND [Currencies].[OnOpener]<>0) AND ((((((([Currencies].[CurrencyType]='ctUSCoin' OR [Currencies].[CurrencyType]='ctMiscellaneousUS') OR [Currencies].[CurrencyType]='ctUSCash') OR [Currenc
                      |    |--Nested Loops(Left Outer Join, OUTER REFERENCES:([Currencies].[CurrencyGUID], [Openers].[OpenerGUID]) WITH PREFETCH)
                      |         |--Filter(WHERE:([Openers].[SessionGUID]=[@SessionGUID]))
                      |         |    |--Concatenation
                      |         |         |--Nested Loops(Left Outer Join)
                      |         |         |    |--Table Spool
                      |         |         |    |    |--Hash Match(Inner Join, HASH:([Windows].[WindowGUID])=([Openers].[WindowGUID]), RESIDUAL:([Windows].[WindowGUID]=[Openers].[WindowGUID]))
                      |         |         |    |         |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Windows].[IX_Windows_CageGUID]))
                      |         |         |    |         |--Table Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Openers]))
                      |         |         |    |--Table Spool
                      |         |         |         |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))
                      |         |         |--Compute Scalar(DEFINE:([Openers].[OpenerGUID]=NULL, [Openers].[SessionGUID]=NULL, [Windows].[UseChipDenominations]=NULL))
                      |         |              |--Nested Loops(Left Anti Semi Join)
                      |         |                   |--Clustered Index Scan(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[IX_Currencies_CurrencyType]))
                      |         |                   |--Row Count Spool
                      |         |                        |--Table Spool
                      |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID] AND [OpenerDetails].[CurrencyGUID]=[Cu
                      |--Hash Match(Cache, HASH:([Openers].[OpenerGUID]), RESIDUAL:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]))
                           |--Stream Aggregate(DEFINE:([Expr1006]=SUM([partialagg1034]), [Expr1007]=SUM([partialagg1035]), [Expr1008]=SUM([partialagg1036]), [Expr1009]=SUM([partialagg1037]), [Expr1010]=SUM([partialagg1038]), [Expr1011]=SUM([partialagg1039]
                                |--Nested Loops(Inner Join)
                                     |--Stream Aggregate(DEFINE:([partialagg1034]=SUM(If (((([Currencies].[CurrencyType]='ctMiscellaneous' OR [Currencies].[CurrencyType]='ctTokens') OR [Currencies].[CurrencyType]='ctChips') OR [Currencies].[CurrencyType]='
                                     |    |--Nested Loops(Inner Join, OUTER REFERENCES:([OpenerDetails].[CurrencyGUID]) WITH PREFETCH)
                                     |         |--Clustered Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[OpenerDetails].[IX_OpenerDetails_OpenerGUIDCurrencyGUID]), SEEK:([OpenerDetails].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)
                                     |         |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Currencies].[PK_Currencies_CurrencyGUID]), SEEK:([Currencies].[CurrencyGUID]=[OpenerDetails].[CurrencyGUID]) ORDERED FORWARD)
                                     |--Index Seek(OBJECT:([GrobManagementSystemLive].[dbo].[Openers].[IX_Openers_OneOpenerPerSession]), SEEK:([Openers].[OpenerGUID]=[Openers].[OpenerGUID]) ORDERED FORWARD)

Zły-jeden jest chętny do szpulowania 6 milionów wierszy; drugi nie jest.

Uwaga: to nie jest pytanie o strojenie zapytania. Mam pytanie, które działa błyskawicznie. Chcę tylko aby SQL Server Uruchom szybko z procedury składowanej.

Author: Ian Boyd, 2009-01-14

12 answers

Miałem ten sam problem co oryginalny plakat, ale cytowana odpowiedź nie rozwiązała problemu dla mnie. Zapytanie nadal działało bardzo wolno z procedury składowanej.

Znalazłem inną odpowiedź tutaj "parameter Sniffing" , dzięki Omnibuzz. Sprowadza się do używania "zmiennych lokalnych" w zapytaniach procedur składowanych, ale przeczytaj oryginał, aby lepiej zrozumieć, jest to świetny zapis. np.

Slow way:

CREATE PROCEDURE GetOrderForCustomers(@CustID varchar(20))
AS
BEGIN
    SELECT * 
    FROM orders
    WHERE customerid = @CustID
END

Szybki sposób:

CREATE PROCEDURE GetOrderForCustomersWithoutPS(@CustID varchar(20))
AS
BEGIN
    DECLARE @LocCustID varchar(20)
    SET @LocCustID = @CustID

    SELECT * 
    FROM orders
    WHERE customerid = @LocCustID
END

Nadzieja pomaga to komuś innemu, skracając mój czas wykonania z 5 + minut do około 6-7 sekund.

 334
Author: Adam Marshall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-07 11:53:39

Znalazłem problem, Oto skrypt powolnych i szybkich wersji procedury składowanej:

dbo.ViewOpener__RenamedForCruachan__Slow.PRC

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS OFF 
GO

CREATE PROCEDURE dbo.ViewOpener_RenamedForCruachan_Slow
    @SessionGUID uniqueidentifier
AS

SELECT *
FROM Report_Opener_RenamedForCruachan
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

dbo.ViewOpener__RenamedForCruachan__Fast.PRC

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO

CREATE PROCEDURE dbo.ViewOpener_RenamedForCruachan_Fast
    @SessionGUID uniqueidentifier 
AS

SELECT *
FROM Report_Opener_RenamedForCruachan
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank
GO

SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
Jeśli nie zauważyłeś różnicy, nie winię cię. Różnica Nie dotyczy w ogóle procedury składowanej. Różnica, która zamienia szybkie zapytanie o koszt 0,5 w takie, które wykonuje gorliwą szpulę 6 milionów wierszy:

Slow: SET ANSI_NULLS OFF

Szybko: SET ANSI_NULLS ON


Ta odpowiedź również może mieć sens, ponieważ Widok ma klauzulę join, która mówi:]}
(table.column IS NOT NULL)

Więc jest kilka NULLzaangażowanych.


Wyjaśnienie jest dalej udowodnione przez powrót do analizatora zapytań i uruchomienie

SET ANSI_NULLS OFF

.

DECLARE @SessionGUID uniqueidentifier
SET @SessionGUID = 'BCBA333C-B6A1-4155-9833-C495F22EA908'

.

SELECT *
FROM Report_Opener_RenamedForCruachan
WHERE SessionGUID = @SessionGUID
ORDER BY CurrencyTypeOrder, Rank

I zapytanie jest powolne.


Więc problemem nie jest ponieważ zapytanie jest uruchamiane z procedury składowanej. Problem w tym, że Domyślną opcją połączenia Enterprise Manager jest ANSI_NULLS off, a nie ANSI_NULLS on, co jest domyślną opcją QA.

Microsoft uznaje ten fakt w KB296769 (błąd: nie można używać SQL Enterprise Manager do tworzenia procedur składowanych zawierających połączone obiekty serwera). Obejście problemu polega na dodaniu opcji ANSI_NULLS w oknie dialogowym procedury składowanej:

Set ANSI_NULLS ON
Go
Create Proc spXXXX as
....
 123
Author: Ian Boyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-07 12:06:29

Zrób to dla swojej bazy danych. Mam ten sam problem - działa dobrze w jednej bazie danych, ale kiedy kopiuję tę bazę danych do innej przy użyciu importu SSIS (nie zwykłego przywracania), ten problem dzieje się z większością moich procedur składowanych. Tak więc po googlowaniu trochę więcej, znalazłem blog Pinal Dave (który btw, spotkałem większość jego postu i pomógł mi bardzo, więc dzięki Pinal Dave) .

Wykonuję poniższe zapytanie w mojej bazie danych i to poprawiło mój problem:

EXEC sp_MSforeachtable @command1="print '?' DBCC DBREINDEX ('?', ' ', 80)"
GO
EXEC sp_updatestats
GO 
Mam nadzieję, że to pomoże. Przekazuję pomoc innym, którzy pomogli mi.
 17
Author: Carenski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-07 12:10:54

Miałem do czynienia z tym samym problemem i ten post był dla mnie bardzo pomocny, ale żadna z zamieszczonych odpowiedzi nie rozwiązała mojego konkretnego problemu. Chciałem opublikować rozwiązanie, które działało dla mnie w nadziei, że może pomóc komuś innemu.

Https://stackoverflow.com/a/24016676/814299

Na końcu zapytania Dodaj opcję (OPTIMIZE FOR (@now UNKNOWN))

 7
Author: jessieloo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-31 15:58:13

Tym razem znalazłeś swój problem. Jeśli następnym razem będziesz miał mniej szczęścia i nie możesz tego rozgryźć, możesz użyć Plan freezing i przestać martwić się o zły plan wykonania.

 4
Author: A-K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-08 02:37:48

Doświadczałem tego problemu. Moje zapytanie wyglądało mniej więcej tak:

select a, b, c from sometable where date > '20140101'

Moja procedura składowana została zdefiniowana następująco:

create procedure my_procedure (@dtFrom date)
as
select a, b, c from sometable where date > @dtFrom

Zmieniłem typ danych na datetime i voila! Od 30 minut do 1 minuty!

create procedure my_procedure (@dtFrom datetime)
as
select a, b, c from sometable where date > @dtFrom
 3
Author: Lee Tickett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-06 08:54:59

Czy próbowałeś przebudować statystyki i / lub indeksy w tabeli Report_Opener. Wszystkie rekomplikacje SP nie będą nic warte, jeśli Statystyki nadal pokażą dane z czasu pierwszej inauguracji bazy danych.

Początkowe zapytanie działa szybko, ponieważ optymalizator widzi, że parametr nigdy nie będzie null. W przypadku SP optymalizator nie może być pewien, że parametr nigdy nie będzie null.

 1
Author: AnthonyWJones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 21:57:54

Chociaż zazwyczaj jestem przeciwko (choć w tym przypadku wydaje się, że masz prawdziwy powód), Czy próbowałeś podać jakieś podpowiedzi do zapytania w wersji SP zapytania? Jeśli SQL Server przygotowuje inny plan wykonania w tych dwóch instancjach, czy możesz użyć podpowiedzi, aby powiedzieć, jakiego indeksu użyć,aby plan pasował do pierwszego?

Kilka przykładów można znaleźć tutaj .

EDIT: jeśli możesz zamieścić tutaj swój plan zapytań, być może uda nam się zidentyfikować jakąś różnicę między tymi planami.

Po drugie: Zaktualizowano link do SQL-2000. Będziesz musiał przewijać w dół, ale jest drugi zatytułowany "wskazówki do tabeli", który jest tym, czego szukasz.

Po trzecie:" złe "zapytanie zdaje się ignorować [IX_Openers_SessionGUID] w tabeli "Openers" - czy jest szansa, że dodanie podpowiedzi do indeksu, aby zmusić go do użycia tego indeksu zmieni coś?

 1
Author: SqlRyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 23:07:46

Jest to prawdopodobnie mało prawdopodobne, ale biorąc pod uwagę, że Twoje obserwowane zachowanie jest nietypowe, należy je sprawdzić i nikt inny o tym nie wspomniał.

Czy jesteś absolutnie pewien, że wszystkie obiekty są własnością dbo i nie masz nieuczciwych kopii należących do ciebie lub innego użytkownika?

Tylko czasami, gdy widziałem dziwne zachowanie, to dlatego, że były w rzeczywistości dwie kopie obiektu i który z nich otrzymasz zależy od tego, co jest określone i Kto ty są zalogowani jako. Na przykład możliwe jest posiadanie dwóch kopii widoku lub procedury o tej samej nazwie, ale posiadanych przez różnych właścicieli - sytuacja, która może się zdarzyć, gdy nie jesteś zalogowany do bazy danych jako dbo i zapominasz określić dbo jako właściciela obiektu podczas tworzenia obiektu.

Zauważ, że w tekście uruchamiasz pewne rzeczy bez podania właściciela, np.

sp_recompile ViewOpener

Jeśli na przykład tam, gdzie znajdują się dwie kopie viewOpener należące do dbo i [niektóre inny użytkownik] następnie, który z nich faktycznie przekompilujesz, jeśli nie podasz, zależy od okoliczności. Tak samo w przypadku widoku Report_Opener-jeśli istnieją dwie kopie (które mogą różnić się specyfikacją lub planem wykonania), to to, co jest używane, zależy od okoliczności - a ponieważ nie określasz właściciela, jest całkowicie możliwe, że Twoje zapytanie adhoc może użyć jednej, a skompilowana procedura może użyć drugiej.

Jak mówię, to prawdopodobnie mało prawdopodobne, ale jest to możliwe i powinno być sprawdzone, ponieważ twoje problemy mogą być takie, że po prostu szukasz błędu w niewłaściwym miejscu.

 1
Author: Cruachan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-14 09:57:32

Może to zabrzmieć głupio i wydaje się oczywiste z nazwy SessionGUID, ale czy kolumna jest unikalnym identyfikatorem na Report_Opener? Jeśli nie, możesz spróbować przerzucić go na właściwy typ i dać mu szansę lub zadeklarować zmienną na właściwy typ.

Plan stworzony w ramach sproc może działać nieintuitywnie i wykonać wewnętrzny odlew na dużym stole.

 1
Author: David Rendall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-15 16:45:43

Mam inny pomysł. Co zrobić, jeśli utworzysz tę funkcję opartą na tabeli:

CREATE FUNCTION tbfSelectFromView
(   
    -- Add the parameters for the function here
    @SessionGUID UNIQUEIDENTIFIER
)
RETURNS TABLE 
AS
RETURN 
(
    SELECT *
    FROM Report_Opener
    WHERE SessionGUID = @SessionGUID
    ORDER BY CurrencyTypeOrder, Rank
)
GO

A następnie wybrany z niego za pomocą następującej instrukcji (nawet umieszczając to w swoim SP):

SELECT *
FROM tbfSelectFromView(@SessionGUID)

Wygląda na to, że to, co się dzieje (co wszyscy już skomentowali), to to, że SQL Server po prostu tworzy założenie gdzieś, które jest złe, i może to zmusi go do poprawienia założenia. Nie chcę dodawać dodatkowego kroku, ale nie wiem, co jeszcze może go powodować.

 0
Author: SqlRyan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-13 23:15:57

-- Oto rozwiązanie:

create procedure GetOrderForCustomers(@CustID varchar(20))

as

begin

select * from orders

where customerid = ISNULL(@CustID, '')

end

-- That ' s it

 0
Author: Koldoon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-12-12 23:56:48