konto usunięte

Temat: Szybkość procedury vs. adhoc query

Zamieszczam obiecany dowód.
Potrzebna jest baza AdventureWorksLT2008, projekt w VS2010. Oto kod w C# tworzący zapytanie, cały projekt zamieściłem tutaj:
const string CONN_STR = @"Data Source=.;Initial Catalog=AdventureWorksLT2008;Integrated Security=True";
static void Main() {
string[] _filters = { "Red","Blue","Yellow" };
//AdventureWorksDataContext został wygenerowany w dbmlu
using(var db = new Linq2SQL.AdventureWorksDataContext(CONN_STR)) {
db.Log = Console.Out;
foreach(string _filter in _filters) {
db.Products //from SalesLT.Products
.Where(p => p.Name.Contains(_filter)) //where Name like '%filter%'
.Select(p => new { p.Name,p.Color }) //select Name,Color
.ToList(); //execute
}
}
}

a oto zapytanie SQL które odpytuje cache query planów - zwracam uwagę na kolumnę usecounts gdyż to jej licznik ma kluczowe znaczenie dla dowodu, czy plan jest używany
select p.usecounts, t.[text]
from sys.dm_exec_cached_plans p
cross apply sys.dm_exec_sql_text(plan_handle) t
where text LIKE N'%![SalesLT!].![Product!] AS ![t0!]%' escape '!' and text not like N'%dm_exec_cached_plans%';

no i jeszcze komenda do czyszczenia cache'u:
DBCC FREEPROCCACHE;
DBCC FREESYSTEMCACHE('ALL');
- warto przeczyścić przed startem testu.

W .NET 4.0 wszystko używa tego samego planu, bo Linq parametryzuje parametr jako nvarchar(4000), w 3.5 było (i jest) trochę gorzej, bo... sami zobaczcie jak Linq parametryzuje stałe, wspominałem o tym jakiś czas temu w polemice z Przemkiem - jakoś nikt poza mną się tym nie zmartwił i nie opisał, jak to jest w innych ORMach:)

Zachęcam do samodzielnego grzebania zarówno we wnętrzościach SQL Servera (np. sys.dm_exec_cached_plans) jak i innych ORMach, Linq2SQL jest dość młody i jak widać dojrzewa. W sieci często są już nieaktualne informacje na jego temat.

Na koniec moje zdanie: nawet, gdyby kiedyś ilość query planów była dla nas problemem to:
- koszt produkcji softu bez ORMa: dość duży
- kostka pamięci RAM i/lub konsultacja dobrego DBA w kwestii tuningu instancji produkcyjnego SQL Servera: niski
Mówię to z punktu widzenia osoby, która i soft tworzy od zera, i martwi się potem jak on działa już po wdrożeniu. Gdybym był tylko DBA to oczywiście ORMów bym zakazał, podobnie jak każdy admin zakazałby luserom dostępu do sieci:)
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Szybkość procedury vs. adhoc query

maciek kański:

Dzięki, sprawdzę w wolnej chwili.. na razie jedno pytanie trochę z beczki:

.Where(p => p.Name.Contains(_filter)) //where Name like '%filter%'


To wysyła dosłownie '%string%'? Bo %% wymusza full table scan.

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Bartosz Ślepowronski:
To wysyła dosłownie '%string%'?
Powinieneś mi za fatygę odpalić to piwo, które na zdjęciu wypijasz:) Oto zrzut z SQL profilera:
exec sp_executesql N'SELECT [t0].[Name], [t0].[Color]
FROM [SalesLT].[Product] AS [t0]
WHERE [t0].[Name] LIKE @p0',N'@p0 nvarchar(4000)',@p0=N'%Red%'

Bo %% wymusza full table scan.
Ano w tym wypadku wymusza (dokładnie clustered index scan) ale to chyba inny temat:)

BTW: samo Linq2SQL twierdzi (DataContext.Log), że generuje coś takiego:
SELECT [t0].[Name], [t0].[Color]
FROM [SalesLT].[Product] AS [t0]
WHERE [t0].[Name] LIKE @p0

polecam zawsze kontrolowanie działania ORMa przez profilera - to jest najpewniesze źródło informacji.
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Bo %% wymusza full table scan.
Ano w tym wypadku wymusza (dokładnie clustered index scan) ale to chyba inny temat:)

?
Rezultatem użycia like '%string%' jest ignorowanie indexu na danej kolumnie i sprawdzanie kazdego rekordu w tabel. Stąd moje pytanie, bo taki SQL byłby szalenie nieefektywny dla większych tabel. W tym konkretnym przykładzie tak czy inaczej dane w tabeli są mało selektywne oraz jest za malo wierszy zeby optimizer użył indexów non clustered, więc nie ma to znaczenia.

Przykład jest oparty na bardzo małej tabeli i prostym selekcie - dla tego przypadku zapisany plan jest tak prosty, że w zasadzie nie ma sensu go analizować. Wystarczy powiedzieć, że dla bardzo prostych zapytań szansa na znalezienie zapytania w cache jest wystarczająco duża duża.

Ciekaw jestem jak by to wyglądało dla zapytania np. z kilkoma joinami na większych tabelach, ale domyślam się że dla takich przypadków nie używa się bezpośrednio ORM tylko raczej tworzy widok i odpala proste zapytanie do widoku?Bartosz Ślepowronski edytował(a) ten post dnia 25.07.10 o godzinie 00:44

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Bartosz Ślepowronski:
Rezultatem użycia like '%string%' jest ignorowanie indexu na danej kolumnie i sprawdzanie kazdego rekordu w tabel. Stąd moje pytanie, bo taki SQL byłby szalenie nieefektywny dla większych tabel. W tym konkretnym przykładzie tak czy inaczej dane w tabeli są mało selektywne oraz jest za malo wierszy zeby optimizer użył indexów non clustered, więc nie ma to znaczenia.
Nie rozumiem celu dyskusji. Zaproponuj inne rozwiązanie dla wymogu klienta: 'proszę o listę produktów, które w nazwie zawierają słowo Czerwony'. Jak znasz lepsze zapytanie - cokolwiek to lepsza oznacza - to dawaj.
Ciekaw jestem jak by to wyglądało dla zapytania np. z kilkoma joinami na większych tabelach
Znalezienie planu w cache to jedno. To, czy plan jest optymalny to drugie. Moim celem było wykazanie pierwszego i ponieważ Linq2SQL jest deterministyczny i zawsze generuje tę samą treść (nie licząc kwestii parametryzacji stringów w v3.5) zostanie ona odnaleziona w cache sql servera, czego należało dowieść. Jak nadal wątpisz - daj kontrprzykład miast teoretyzować:)

ale domyślam się że dla takich przypadków nie używa się bezpośrednio ORM tylko raczej tworzy widok i odpala proste zapytanie do widoku?
Ja tak robię (dokładnie wolę table value function) ale wynika to przede wszystkim z zasady rozdzielania warstw w projekcie - zmieniając schemę bazy danych nie chcę rekompilować projektu i robić deploya. Chodzi zatem o czystą enkapsulację, przynajmniej dla mnie, możliwość głębszego optymalizowania query oraz używania konstrukcji niedostępnych z ORMa są wartościami dodanymi.

Bartek teraz pytanie do Ciebie: jesteś DBA, musisz zaproponować rozwiązanie, które umożliwi klientowi odpytywanie logicznych obiektów z bazy danych z umożliwienie pageowania, sortowania i filtrowania po każdej kolumnie. Zaproponuj rozwiązanie:
- sklejanie stringów w locie po stronie aplikacji
- sklejanie stringów w locie po stronie SP
- SP
- użycie ORMa
- twoje własne?
Pisząc filtrowanie mam na myśli podstawowe możliwości czyli:
- dla wartości liczbowych i dat operatory =, <, >
- dla stringów =, StartsWith (like 'filtr%'), Contains (like '%filtr%')
Zakładając, że wybierzesz SP chciałbym abyś oszacował ilość linijek kodu w takiej procedurze. Załóż, że tabelka ma [n] kolumn i 50% kolumn to stringi, 50% to wartości numeryczne/daty.
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Nie rozumiem celu dyskusji. Zaproponuj inne rozwiązanie dla wymogu klienta: 'proszę o listę produktów, które w nazwie zawierają słowo Czerwony'. Jak znasz lepsze zapytanie - cokolwiek to lepsza oznacza - to dawaj.

Nie ma dyskusji, to było pytanie poboczne. Klientowi powiedziałbym, że zapytanie spełniające jego wymaganie może być bardzo niefektywne, wytłumaczył dlaczego i zaproponował stworzenie nowej kolumny trzymającej atrybut koloru i utworzenie na niej indeksu. Wybór należy do klienta, ale przynajmniej jak będzie musiał czekać minute na wynik zapytania do bazy to będzie wiedział dlaczego.

Ale jak napisałem - to nie ma związku z tematem.
Znalezienie planu w cache to jedno. To, czy plan jest optymalny to drugie.

Powiedziałbym wręcz, że optymalność planu nie ma żadnego znaczenia w naszym case - i nigdzie nie napisałem, że ma.
Bartek teraz pytanie do Ciebie: jesteś DBA, musisz zaproponować rozwiązanie, które umożliwi klientowi odpytywanie logicznych obiektów z bazy danych z umożliwienie pageowania, sortowania i filtrowania po każdej kolumnie. Zaproponuj rozwiązanie:

Sorry, ale to nie jest pytanie do DBA :) Do DBA się przychodzi jak baza "działa powoli" i trzeba sprawdzić dlaczego. Albo jak trzeba postawić nowy cluster.Bartosz Ślepowronski edytował(a) ten post dnia 25.07.10 o godzinie 11:04

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Bartosz Ślepowronski:
Nie ma dyskusji, to było pytanie poboczne.
Dzięki - nie lubię w jednym wątku gadać o dwóch różnych sprawach. Jedna klasa -> jedna odpowiedzialność, jeden wątek -> jeden temat:)
powiedziałbym, że zapytanie spełniające jego wymaganie może być bardzo niefektywne, wytłumaczył dlaczego i zaproponował stworzenie nowej kolumny trzymającej atrybut koloru
Na Allegro można wyszukiwać na podstawie dowolnego stringa w dowolnym miejscu - zero szans na zdefiniwanie atrybutu w każdym przypadku. Dobra, wiem że w takiej sytuacji relacyjne bazy danych nie są najlepsze ale jak to dobrze ująłeś, technicznie nic więcej nie da się zrobić (jedynie rozegrać to odpowiednio z klientem - tu zawsze jest co optymalizować)
Sorry, ale to nie jest pytanie do DBA :)
Czy brak odpowiedzi oznacza, że się ze mną zgadzasz, że ORM jest tutaj niezastąpiony, czy też masz zdanie przeciwne i zechcesz je poprzeć konkretnym przykładem? :)
Gdy ja oddaję aplikację to każda kolumna w tabelce ma się sortować i filtrować (paging oczywisty bo człowiek nie ogarnie tysiąca rekordów na ekranie) - chciałbym wiedzieć, jakie rozwiązanie poza ORMem ktoś mi zaproponuje.

Z czasów sprzed ORMa pamiętam chamskie sklejanie stringów - czy to w aplikacji czy na serwerze - i nikt się żadnym cache'owaniem planów lub ich ilością nie martwił. Nagle jak się ORM pojawił to się o wydajność wszyscy zaczęli martwić;)
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Sorry, ale to nie jest pytanie do DBA :)
Czy brak odpowiedzi oznacza, że się ze mną zgadzasz, że ORM jest tutaj niezastąpiony, czy też masz zdanie przeciwne i zechcesz je poprzeć konkretnym przykładem? :)

Oznacza tyle, że nie wiem, nie jestem developerem, nie znam się na programowaniu, nie potrafię napisać własnej aplikacji bardziej skomplikowanej niż form + kilka przycisków więc nie będę się na ten temat mądrzył. Znam się mniej więcej na tym jak działa SQL server, jakiej logiki używa jego silnik, itd. Analizuję problem z tej perspektywy.

Dla mnie normalna jest taka sytuacja, że 1) ktoś sie skarży że coś działa zbyt wolno 2) odpalam swoje zabawki i sprawdzam gdzie jest problem 3) jeśli problem leży w kodzie kontaktuję się z developerem, tłumaczę w czym jest problem (szukanie po '%string%' jest powszechne..) i jak to zmienić od strony zapytania, żeby było lepiej.
Problemem developera jest zmiana aplikacji w taki sposób, żeby wysyłałą efektywne zapytania. Jak ma to zrobić - to jest jego działka, każdy robi to na czym sie zna. Czasem się nie da i trzeba albo zakceptować spadek wydajności albo wyłożyć $$$ na hardware.

To tak offtopując.
Na Allegro można wyszukiwać na podstawie dowolnego stringa w dowolnym miejscu

Full Text Index + masa magicznych rozwiązań polepszających wydajność.Bartosz Ślepowronski edytował(a) ten post dnia 25.07.10 o godzinie 12:08

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Bartosz Ślepowronski:
Problemem developera jest zmiana aplikacji w taki sposób, żeby wysyłałą efektywne zapytania. Jak ma to zrobić - to jest jego działka
Dobrze ujęte, developer odpowiada za to co wysyła. Jak ma zepsuć to zepsuje niezależnie od tego, czy używa ORMa czy SP. Nie zrzucajmy winy na bezmyślne narzędzia.

Natomiast w kwestii szybszego pisania softu, nawet wywołanie SP wolę robić przez Linq, zamiast:
using(var conn = new SqlConnection(@"conn str")) {
using(var cmd = new SqlCommand("dbo.nazwa_procedury",conn) { CommandType = CommandType.StoredProcedure }) {
cmd.Parameters.Add("@customer_id",SqlDbType.Int).Value = customer_id;
if(null==order_date) cmd.Parameters.Add("@order_date",SqlDbType.DateTime).Value = DBNull.Value;
else cmd.Parameters.Add("@order_date",SqlDbType.DateTime).Value = order_date.Value;
cmd.Parameters.Add("@count",SqlDbType.Int).Value = count;
var sqlParam = cmd.Parameters.Add("@param_out",SqlDbType.Int);
sqlParam.Direction = ParameterDirection.Output;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
if(DBNull.Value != sqlParam.Value) param_out = (int)sqlParam.Value;
}
}
wystarczy
using(var db = new DataBaseContext(@"conn str")) {
db.nazwa_procedury(customer_id,order_date,count,ref param_out);
}
nie licząc tego, że błędy Linq2SQL wykrywa już w czasie kompilacji!!!

konto usunięte

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Natomiast w kwestii szybszego pisania softu, nawet wywołanie SP wolę robić przez Linq

a co stoi na przeszkodzie żeby mieć jakąś klasę po środku która pewne sprawy ułatwi?

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Przemysław R.:
a co stoi na przeszkodzie żeby mieć jakąś klasę po środku która pewne sprawy ułatwi?
3x kasiora:
- po co pisać klasę, jeżeli istnieje gotowe rozwiązanie w .NET - kto za to zapłaci?
- jakie jest prawdopodobieństwo, że idąc do nowego zespołu spotkam tę samą klasę, czyli koszt nauki nowego rozwiązania - kto za to zapłaci?
- czy ta klasa byłaby weakly czy strongly typed, tj. czy błędną nazwę kolumny wykryję już w czasie kompilacji czy dopiero w runtime? Wcześniejsza detekcja błędów -> niższy koszt produkcji softu, kto ma to sponsorować?

Co prawda widzę też 2 słabe kontrargumenty
- SP która zwraca wiele result set'ów (chyba się nie da przez Linq2SQL)
- ograniczenie architektury do max. .NET 3.0 lub inne polityczne uwarunkowania (spotkałem się z tym)

To teraz Przemek czekam na twoje argumenty za tą 'klasą' :)

konto usunięte

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Przemysław R.:
a co stoi na przeszkodzie żeby mieć jakąś klasę po środku która pewne sprawy ułatwi?
3x kasiora:
- po co pisać klasę, jeżeli istnieje gotowe rozwiązanie w .NET - kto za to zapłaci?

to nie jest jakaś wypas klasa z mega kreatorami
http://www.davidhayden.com/blog/dave/archive/2006/11/0...

przykład tego o czym myślałem, łatwe w implementacji i użyteczne
- jakie jest prawdopodobieństwo, że idąc do nowego zespołu spotkam tę samą klasę, czyli koszt nauki nowego rozwiązania - kto za to zapłaci?

pracodawca
idziesz do nowej roboty, załóżmy znasz tylko Linq, a tam pracują w NH - czy to nie jest sytuacja analogiczna?
- czy ta klasa byłaby weakly czy strongly typed, tj. czy błędną nazwę kolumny wykryję już w czasie kompilacji czy dopiero w runtime? Wcześniejsza detekcja błędów -> niższy koszt produkcji softu, kto ma to sponsorować?

lepsza prosta klasa niż klepanie parametrów jak ta małpa

Co prawda widzę też 2 słabe kontrargumenty
- SP która zwraca wiele result set'ów (chyba się nie da przez Linq2SQL)
- ograniczenie architektury do max. .NET 3.0 lub inne polityczne uwarunkowania (spotkałem się z tym)

To teraz Przemek czekam na twoje argumenty za tą 'klasą' :)

argument jest jeden prosta klasa będąca pośrednikiem między tym co chcę zrobić a bazą danych jest ok, jest zdecydowanie lepsza od gołego ADO.NET. nie robimy robimy aż takiego spagetti z kodu, ni i nie powtarzamy jednostajnych czynności przy wykonywaniu procedury, jedna linia i po krzyku
nie licząc tego, że błędy Linq2SQL wykrywa już w czasie kompilacji!!!

sam z siebie to robi czy trzeba mu pomóc jakimś kreatorem?
idąc tym tropem przy odpowiednio rozbudowanej klasie, posiadającej jakieś pliki konfiguracyjne, kreatory etc. osiągniemy dokładnie ten sam efekt, a chyba nie chodzi o to

ps. przy okazji jeżeli prezentujesz kod, a powiedzmy zawodowcem w tej materi nie jestem, to jak widzę to aż mi się scyzoryk w kieszeni otwiera
pleas napisz że to nie twoje ;)

var sqlParam = cmd.Parameters.Add("@param_out",SqlDbType.Int);
sqlParam.Direction = ParameterDirection.Output;

lub

if(null==order_date) cmd.Parameters.Add("@order_date",SqlDbType.DateTime).Value = DBNull.Value;
else cmd.Parameters.Add("@order_date",SqlDbType.DateTime).Value = order_date.Value;

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Przemysław R.:
argument jest jeden prosta klasa będąca pośrednikiem między tym co chcę zrobić a bazą danych jest ok, jest zdecydowanie lepsza od gołego ADO.NET.
Pytanie było nie czy klasa jest lepsza od gołego ADO.NET, ale w czym jest lepsza od Linq2SQL.
W związku z tym ponieważ ominąłeś temat ponawiam pytanie, dlaczego chcesz pisać własną klasę (lub googlować w jej poszukiwaniu) - uzasadnij w jaki sposób jest ona lepsza od Linq2SQL i w jaki sposób zwrócą się koszta jej:
- stworzenia (Linq jest gratis)
- przetestowania (Linq jest dobrze przetestowane przez team w M$)
- nauki (Linq jest w standardowym zestawie szkoleń M$)
pleas napisz że to nie twoje ;)
mój kod, co gorsza robię tak od 2003r (z wyjątkiem słowa kluczowego var które jest od ok. 2lat dopiero). Cenię sobie każdą okazję do code review bo sam chciałbym się poprawić, podobnie jak i inni czytający wątek, oczekuję więc, że:
- napiszesz co w tym kodzie jest złe
- napiszesz, dlaczego jest nie tak
- zaproponujesz rozsądną poprawę

Bardzo Cię proszę o wyraźne uzasadnienie swoich poglądów, bo nie pierwszy raz muszę od Ciebie argumenty wyciągać.

konto usunięte

Temat: Szybkość procedury vs. adhoc query

maciek kański:
Przemysław R.:
argument jest jeden prosta klasa będąca pośrednikiem między tym co chcę zrobić a bazą danych jest ok, jest zdecydowanie lepsza od gołego ADO.NET.
Pytanie było nie czy klasa jest lepsza od gołego ADO.NET, ale w czym jest lepsza od Linq2SQL.

Jest dynamiczna - umożliwia obsługę nowych procedur bez konieczności przebudowy aplikacji, co w pewnych okolicznościach jest kłopotliwe

Zmniejsza narzut na kodowanie - ale dokładnie to samo robi linq
W związku z tym ponieważ ominąłeś temat ponawiam pytanie, dlaczego chcesz pisać własną klasę (lub googlować w jej poszukiwaniu) - uzasadnij w jaki sposób jest ona lepsza od Linq2SQL i w jaki sposób zwrócą się koszta jej:
- stworzenia (Linq jest gratis)
- przetestowania (Linq jest dobrze przetestowane przez team w M$)
- nauki (Linq jest w standardowym zestawie szkoleń M$)

Odczuwam dziką satysfakcję jak nie muszę rekompilować projektu po każdym dodaniu procedury.
np. mam maszynę do generowania raportów, dodam raport -> procedurę, w Linq niestety muszę całość przemodelować, w dynamicznym podejściu nawet nie zauważam

W tym konkretnym zadaniu linq się trochę nie sprawdza, w innym pewnie będzie inaczej
pleas napisz że to nie twoje ;)
mój kod, co gorsza robię tak od 2003r (z wyjątkiem słowa kluczowego var które jest od ok. 2lat dopiero). Cenię sobie każdą okazję do code review bo sam chciałbym się poprawić, podobnie jak i inni czytający wątek, oczekuję więc, że:
- napiszesz co w tym kodzie jest złe
- napiszesz, dlaczego jest nie tak
- zaproponujesz rozsądną poprawę

1 przypadek - SqlCommandBuilder.DeriveParameters
czemu nie korzystasz? w procedurze masz zdefiniowany typ parametru
popatrz na argumenty które pisałeś przy Linq na początku

2 przypadek - brak definicji prametru to też parametr jak po stronie procedury SQL masz wartość domyślne

CREATE PROCEDURE HumanResources.uspGetEmployees
@LastName nvarchar(50) = 'ktos',
@FirstName nvarchar(50) = Null
AS

SET NOCOUNT ON;
SELECT FirstName, LastName, JobTitle, Department
FROM HumanResources.vEmployeeDepartment
WHERE FirstName = @FirstName AND LastName = @LastName;

jak nie podasz @FirstName, SQL przyjmie wartość zadeklarowaną w nagłówku

zresztą konstrukcja jakaś mega wielka, można zawsze wykorzystać coś na wzór ISNULL(warość, warość), napisać cokolwiek, taka funkcja jest jakby to powiedzieć uniwersalna i do wielokrotnego wykorzystania
Bardzo Cię proszę o wyraźne uzasadnienie swoich poglądów, bo nie pierwszy raz muszę od Ciebie argumenty wyciągać.

a mógł bym prosić żebyś w przyszłości nie wykorzystywał mojej osoby do pokazywania czegokolwiek. w tym wątku zrobiłeś to już dwukrotnie
nie to żebym się wstydził, czuję tylko pewien niesmak

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Przemysław R.:
np. mam maszynę do generowania raportów, dodam raport -> procedurę, w Linq niestety muszę całość przemodelować, w dynamicznym podejściu nawet nie zauważam
i dobrze robisz, przy takich wymaganiach raportowych jest oczywiste, że wszelkie statyczne mapowania nie wchodzą w grę. Ale jak sam piszesz:
W tym konkretnym zadaniu linq się trochę nie sprawdza, w innym pewnie będzie inaczej
w moim przypadku Linq się jak najbardziej sprawdza, więc to jest odpowiedź na twoje pytanie, czemu klasa pośrednicząca jest bez sensu.
1 przypadek - SqlCommandBuilder.DeriveParameters
czemu nie korzystasz?
W moim przypadku, kiedy znam strukturę procedury SqlCommandBuilder.DeriveParameters jest rozwiązaniem wysoce nieefektywnym o czym można wyczytać bezpośredni na MSDNie. Dlaczego? Ano dlatego, że wykonuje zbędnego w moim przypadku roundtripa do SQL Servera (aby wywołać sp_procedure_params_100_managed) i potem dopiero w kolejnym roundtripie wywołuje właściwą procedurę. Narzut sieci w przypadku łącza tcp/ip może być kosztowny, w każdym razie jest kompletnie nieuzasadniony, jeżeli procedura jest znana (vide: blokowanie połączenia z connection poola)

Uzasadniony jest tylko przy dynamicznym rozpoznawaniu procedury, zapewne nowej i zgodnie z twoim wstępem mogę się domyślać, że dla Ciebie ma to sens. Ale nie rozumiem po co mi radzisz coś takiego skoro dobrze widzisz, że ja znam schemę bazy danych?
Jak ktoś chce się przekonać, dwa narzędzia:
- sql profiler (jak zawsze)
- SqlConnection.StatisticsEnabled (pola ServerRoundtrips, NetworkServerTime, ConnectionTime)
2 przypadek - brak definicji prametru to też parametr jak po stronie procedury SQL masz wartość domyślne
do tej pory dobrze, ale opisałeś tylko 1 przypadek na 3. Bo są jeszcze takie:
- parametr nie ma defaulta
- parametr posiadana inny niż null default.
I w takiej sytuacji zwykły null nie zadziała:
cmd.Parameters["@FirstName"].Value = null;
tylko trzeba explicite podstawić DbNull.Value:
cmd.Parameters["@FirstName"].Value = DBNull.Value;

Argument o scyzoryku obalony, co najwyżej administratorowi sieci może się otworzyć na widok zbędnych pakietów:)
a mógł bym prosić żebyś w przyszłości nie wykorzystywał mojej osoby do pokazywania czegokolwiek. w tym wątku zrobiłeś to już dwukrotnie
nie to żebym się wstydził, czuję tylko pewien niesmak
Nie zgadzam się (po raz kolejny:) z zarzutem, jakobym cokolwiek z twoją osobą robił. Polemizuję z twoimi poglądami, za którymi oczywiście stoisz Ty, ale skoro bierzesz udział w publicznej i otwartej dyskusji to musisz się liczyć z polemiką która powtórzę, dotyczy nie Ciebie, ale twoich wypowiedzi, a to jednak różnica. Ponadto rozmawiamy cały czas na temat, nie schodzimy z niego.

Natomiast prośba do osób czytających ten wątek - jeżeli ktoś obiektywnie uważa, że zatarła mi się granica między problemem a osobą to proszę o info na priv.

EDIT: literówki, formatowaniemaciek kański edytował(a) ten post dnia 26.07.10 o godzinie 01:09

konto usunięte

Temat: Szybkość procedury vs. adhoc query

Nieprawda że jedna procedura to jeden plan, raz że serwer może ją podzielić na statementy a dwa, że zle sparametryzowana procedura może za każdym razem generować nowy plan, miałem przypadek procedury która generowała ponad 10 tyś planów i bufor robił kaput.

z mojej perspektywy problem zapytań adhock jest inny w większośći przypadków tracimy łańcuch dziedziczenia uprawnień,
łatwo pokusić się też o wsadzenie czegoś brzydkiego do takiego stringa.
Bartosz Ślepowronski

Bartosz Ślepowronski Problem? Jaki
problem?

Temat: Szybkość procedury vs. adhoc query

Robert Kubalski:
Nieprawda że jedna procedura to jeden plan, raz że serwer może ją podzielić na statementy a dwa, że zle sparametryzowana procedura może za każdym razem generować nowy plan, miałem przypadek procedury która generowała ponad 10 tyś planów i bufor robił kaput.

Tak, i o ile dobrze pamiętam to rekompilacja planów dla procedury zależy od wersji MSSQL. W 2000 jeśli procedura miała kilka statementów, rekompilacja planu dla jednego z nich wymuszała rekompilację wszystkich. Od 2005 rekompilowane są tylko te plany które muszą (bo np zmieniły się statystyki). Jeśli ktoś ciągle pracuje na 2000 to warto o tym pamiętać :)

To tak na marginesie.Bartosz Ślepowronski edytował(a) ten post dnia 30.07.10 o godzinie 13:43

Następna dyskusja:

Procedury numeryczne w TSQL




Wyślij zaproszenie do