MSSQL: select jako lista argumentów

0

Hej, mam duży problem z optymalizacją . Potrzebuję dać select jako listę do warunku. Mam tabele dwuelementową @kody. Powiedzmy że składa się z jednej kolumny - 'id' i dwóch wierszy o wartościach 'A', 'B'.
Jeżeli wpisuję ('A','B') na sztywno do zapytania to kręci się w niecałą sekundę.
Jeżeli odpalam sam select, ( (select id COLLATE Polish_CS_AS from @kody)) który jest później listą zapytań, też śmiga szybciutko.
Ale jeżeli select jest już użyty jako argument to zaptytanie kręci się ponad pół godziny i nadal nie ma wyniku..
Czy ma ktoś pomysł co tu jest nie tak? Jak to zoptymalizować ? Co tak zamula ?

DECLARE @kody TABLE (id VARCHAR(10) );
INSERT INTO @kody (id) VALUES('A' )
INSERT INTO @kody (id) VALUES('B' )

SELECT top 5
produkt,
kategoria,
id,
SUM(a) AS suma_a
FROM BAZA.dbo.Tabela
WHERE 1=1
AND [KOD] IN (select id COLLATE Polish_CS_AS from @kody)
GROUP BY
produkt,
kategoria,
id

0

MsSQL prawdopodobnie uruchamia Twój select id ... po kolei dla każdego wiersza (czyli 100 wierszy = 100 dodatkowych zapytań); wykorzystaj CTE.

0

W jaki sposób ? Znam CTE, ale nie bardzo widzę zastosowanie tutaj ... podpowiesz ?

1
Patryk27 napisał(a):

MsSQL prawdopodobnie uruchamia Twój select id ... po kolei dla każdego wiersza

Nie w tym przypadku.

(czyli 100 wierszy = 100 dodatkowych zapytań); wykorzystaj CTE.

Po co od razu CTE?
Zwykły join załatwi sprawę...

declare @kody TABLE (
   id VARCHAR(10)
);

insert into @kody(id) values ('A');
insert into @kody(id) values ('B');

select top 5 
    k.produkt,
    k.kategoria,
    k.id,
    sum(k.a) suma_a
from BAZA.dbo.Tabela a
inner join @kody k on (a.KOD = k.id)
group by k.produkt, k.kategoria, k.id

Poza tym robienie TOP bez ORDER BY nie ma większego sensu.
Ale sam problem jest gdzie indziej, dodaj sortowanie po jakimś indeksie i sprawdź.

0

To był jeden z moich pomysłów - niestety nie rozwiązuje problemu...Nadal się kręci w nieskończoność. Chodzi szybko, tylko w przypadku wpisania parametrów na sztywno :(

To totalnie nowa baza dla mnie - nigdy wcześniej nie pracowałam na MSSQL. Chciałam faktycznie sprawdzić te indeksy, ale z tego co mi się wydaje....to ich nie ma ! może w tym cały problem?
Powiedzcie proszę czy dobrze sprawdzam: wszystkie indeksy na widoku powinny być widoczne w Object Explorer/Nazwa Bazy/Nazwa tabeli/Indexes?

0

Jaki typ ma kolumna kod?
Czy pytasz lokalną bazę, czy zalinkowany serwer?
Jaka wersja mssql-a?

@wloochacz zapomniałeś o COLLATE

@Patryk27 zdradź to ułatwienie z CTE bo nie wiem co to ma ułatwić.

0
technologia napisał(a):

To był jeden z moich pomysłów - niestety nie rozwiązuje problemu...Nadal się kręci w nieskończoność. Chodzi szybko, tylko w przypadku wpisania parametrów na sztywno :(

Co to znaczy na sztywno?

To totalnie nowa baza dla mnie - nigdy wcześniej nie pracowałam na MSSQL. Chciałam faktycznie sprawdzić te indeksy, ale z tego co mi się wydaje....to ich nie ma ! może w tym cały problem?

Nooo... to słabo, jak danych jest sporo.

Powiedzcie proszę czy dobrze sprawdzam: wszystkie indeksy na widoku powinny być widoczne w Object Explorer/Nazwa Bazy/Nazwa tabeli/Indexes?

Tak, ale...
Masz w management studio wbudowany profiler zapytań, użyj go, a od razu powie Ci czy trzeba tam dodać indeks i jaki.

0
Panczo napisał(a):

@wloochacz zapomniałeś o COLLATE

Nie wydaje mi się, ze zapomniałem.
Uważam, że to tam niepotrzebne, skoro wszystko jest w kontekście jednej bazy danych, to zakładam że kolacja jest taka, jak w bazie.
Czyli identyczna.
Aczkolwiek, może być niezbędne, tylko za mało wiemy...

0
Panczo napisał(a):

Jaki typ ma kolumna kod?
nvarchar(20)

Czy pytasz lokalną bazę, czy zalinkowany serwer?
To jest widok w bazie lokalnej ale nie umiem powiedzieć na jakiej tabeli, bo nie znam kodu źródłowego do tego widoku. Da się to z poziomu użytkownika sprawdzić?

Jaka wersja mssql-a?
MS SQL Server Management Studio 18

@wloochacz zapomniałeś o COLLATE

@Patryk27 zdradź to ułatwienie z CTE bo nie wiem co to ma ułatwić.

0
wloochacz napisał(a):
technologia napisał(a):

To był jeden z moich pomysłów - niestety nie rozwiązuje problemu...Nadal się kręci w nieskończoność. Chodzi szybko, tylko w przypadku wpisania parametrów na sztywno :(

Co to znaczy na sztywno?
w sensie, że wpisuję do zapytania in ('A','B') - bez selecta.

To totalnie nowa baza dla mnie - nigdy wcześniej nie pracowałam na MSSQL. Chciałam faktycznie sprawdzić te indeksy, ale z tego co mi się wydaje....to ich nie ma ! może w tym cały problem?

Nooo... to słabo, jak danych jest sporo.
Ale być może źle sprawdziłam... ?

Powiedzcie proszę czy dobrze sprawdzam: wszystkie indeksy na widoku powinny być widoczne w Object Explorer/Nazwa Bazy/Nazwa tabeli/Indexes?

Tak, ale...
Masz w management studio wbudowany profiler zapytań, użyj go, a od razu powie Ci czy trzeba tam dodać indeks i jaki.

Jestem użytkownikiem, mssql krzyczy, ze aby korzystać z tego toolsa, muszę być adminem... :(

0
wloochacz napisał(a):
Panczo napisał(a):

@wloochacz zapomniałeś o COLLATE

Nie wydaje mi się, ze zapomniałem.
Uważam, że to tam niepotrzebne, skoro wszystko jest w kontekście jednej bazy danych, to zakładam że kolacja jest taka, jak w bazie.
Czyli identyczna.
Aczkolwiek, może być niezbędne, tylko za mało wiemy...

Niestety jest niezbędne. Być może źle tego używam, ale na początku próbowałam bez collate to wyskakiwał błąd z tym związany.

0

Czy pytasz lokalną bazę, czy zalinkowany serwer?
To jest widok w bazie lokalnej ale nie umiem powiedzieć na jakiej tabeli, bo nie znam kodu źródłowego do tego widoku. Da się to z poziomu użytkownika sprawdzić?

w ssms prawy klik na widoku i script view as-> alter to

Jaka wersja mssql-a?
MS SQL Server Management Studio 18

to jest wersja ssms, wersje serwera sprawdź zapytaniem: select @@version

I nie pisz posta za postem, spokojnie możesz odpowiedzieć w jednym poście

0
Panczo napisał(a):

Czy pytasz lokalną bazę, czy zalinkowany serwer?
To jest widok w bazie lokalnej ale nie umiem powiedzieć na jakiej tabeli, bo nie znam kodu źródłowego do tego widoku. Da się to z poziomu użytkownika sprawdzić?

w ssms prawy klik na widoku i script view as-> alter to

ok, widok jest robiony przez CTE które korzysta z openquery na innej bazie produkcyjnej. (innej niż ta z której ja korzystam, tamta jest na Mysql)
Z tego co widzę, NIE MA żadnych indeksów... chyba, ze można to sprawdzić jeszcze inaczej niż w Object Explorer i w kodzie tworzenia tabeli...

Jaka wersja mssql-a?
MS SQL Server Management Studio 18

to jest wersja ssms, wersje serwera sprawdź zapytaniem: select @@version

Microsoft SQL Server 2014 (SP2) (KB3171021) - 12.0.5000.0 (X64) Copyright (c) Microsoft Corporation Standard Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)

I nie pisz posta za postem, spokojnie możesz odpowiedzieć w jednym poście

Tak jest! przepraszam :)

0

No to wszystko jasne.

  1. Nie ma indeksów bo widoki ich nie mają.
  2. Trwa to długo, ponieważ cały widok musi być pobrany i przefiltrowany po stronie sql servera

Jedyne obejście to zbudować dynamicznie where:

DECLARE @kody TABLE (id VARCHAR(10) );
declare @lista varchar(8000)
INSERT INTO @kody (id) VALUES('A' )
INSERT INTO @kody (id) VALUES('B' )




SELECT @lista = ''''+substring(STUFF(
             (SELECT ''',''' + id 
              FROM @kody
              FOR XML PATH (''))
             , 1, 1, ''),3,8000)+''''


print @lista	
0

Dziękuję Ci bardzo , a mógłbyś mi proszę pokazać jak tego potem użyć ?
Próbuję
DECLARE @kody TABLE (id VARCHAR(10) );
declare @lista varchar(8000)
INSERT INTO @kody (id) VALUES('A' )
INSERT INTO @kody (id) VALUES('B' )

SELECT @lista = ''''+substring(STUFF(
(SELECT ''',''' + id
FROM @kody
FOR XML PATH (''))
, 1, 1, ''),3,8000)+''''

print @lista
SELECT top 5
produkt,
kategoria,
id,
SUM(a) AS suma_a
FROM BAZA.dbo.Tabela
WHERE 1=1
AND [KOD] IN (@lista )
GROUP BY
produkt,
kategoria,
id

wyrzuca mi brak dopasowań, ale faktycznie kręci się szybko :)
PS: jak można wkleić kod, żeby był taki ładny i czytelny jak Twój?

0
declare @lista varchar(8000)
declare @sql varchar(max)

DECLARE @kody TABLE (id VARCHAR(10) );
INSERT INTO @kody (id) VALUES('A' )
INSERT INTO @kody (id) VALUES('B' )

SELECT @lista = ''''+substring(STUFF(
(SELECT ''',''' + id
FROM @kody
FOR XML PATH (''))
, 1, 1, ''),3,8000)+''''

set @sql = 'SELECT top 5
	produkt,
	kategoria,
	id,
	SUM(a) AS suma_a
FROM 
	BAZA.dbo.Tabela
WHERE 
	1=1
	AND [KOD] IN (' + @lista +')
GROUP BY
	produkt,
	kategoria,
	id'

exec @sql

PS: jak można wkleić kod, żeby był taki ładny i czytelny jak Twój?

```sql
kod sql tutaj
```
0

Uratowałeś mi życie! Dzięki ! :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1