Vlákno názorů k článku Markus Winand: SQL Performance Explained od ps - No mne naskakuje husia koža aj keď vidím...

  • Článek je starý, nové názory již nelze přidávat.
  • 8. 7. 2013 14:40

    ps (neregistrovaný)

    No mne naskakuje husia koža aj keď vidím alternatívu b (ktorá je uvádzaná ako dobrá). Je možno lepšia ako a z performance hľadiska, ale pre mňa dobrá je maximálne ako workaround.
    Predsa SQL interpret musí vedieť implicitne skonvertovať string vo formáte 'YYYY-MM-DD' (poprípade iný vopred daný formát) na dátum. Konverzie dátumov na string a naopak sa má predsa robiť len na UI vrstve.
    Milujem keď čítam zdrojový kód a vidím že developeri hore dole na applikačnej a SQL vrstve konvertujú dátumy na string a naopak.

  • 8. 7. 2013 14:54

    Pavel Stěhule

    V příkladu sale_date = to_date('1970-01-01', 'YYYY-MM-DD') se jedná o explicitní konverzi ze stringu na date. Pokud napíši sale_date = '1970-01-01' tak dojde k téměř k témuž - k implicitní konverzi stringu na date. Použití explicitní konverze patří mezi best practice (minimálně na Oracle), kdy se snižuje závislost chování aplikace na konfiguraci databáze - nejde ani o výkon, ale o blbuvzdornější aplikaci - co vím, tak Oracle konverzi zvládne, bez problémů - předchází se tím ale nastartování UI, kdy se databáze snaží rozpoznat formát.

  • 8. 7. 2013 16:35

    j (neregistrovaný)

    Mno ... nevim jak ktera databaze, ale minimalne nektery ti v pripade varianty A budou provadet konverzi VSECH zaznamu v tabulce na char, aby je slo porovnat s charem, kdezto v pripade druhym, se konverti jednou pred zahajenim dotazu, kterej je o porovnani s konstantou ... coz muze byt i radove rychlejsi.

    Jestli pak budes provadet explicitni nebo implicitni konverzi ... to uz je jen otazka "sychr je sychr", protoze formaty datumu ... to je v databazich kapitola sama pro sebe (stejne jako desetinna tecka vs carka ...).

    Zcela zjevne si nikdy nic zasadniho neresil, protoze jinak by ses nad takovou drobnosti vubec nepodivoval. Ja tu mam trebas M$ SQL a to, v jakym formatu datum zkousne zalezi i na fazi Mesice ... (ja mam EN widle, kolega CZ ... a na problem je zadelano, protoze kdyz mu ja poslu query s implicitni konverzi, on ho proste nespusti a musi si ho predelat).

  • 8. 7. 2013 17:03

    Pavel Stěhule

    Před více než 10 roky jsem na s MS SQL zažil drsné chvíle, kdy server měnil implicitní formát v závislosti, jestli byl na serveru někdo přihlášený nebo ne (přepínal češtinu a angličtinu). Ve chvíli, kdy jsem se tam přihlásil, abych oddebugoval jednu chybu mi aplikační server spadnul na chyby formátů. Takže já osobně tuhle best practicy respektuji.

  • 8. 7. 2013 18:09

    ps (neregistrovaný)

    Len tak naokraj som chcel, že v MSSQL by vás ani CONVERT(DATETIME, 'YYYY-MM-DD') vo všetkých jazykoch nezachránil. CONVERT(DATETIME, 'YYYYMMDD') už áno. Je to relatívne bežný omyl.
    Chápem že situácia je taká aká je a kvôli spätnej kompatibilite sa to tak ľahko nezmení. Len sa mi zdá trochu choré že server musí ešte riešiť aj konverziu dátumov podľa nastaveného jazyka a nie proste striktne vyžaduje len jediný správny formát. Zobrazenie a čítanie dátumov v používateľom požadovanom formáte by podľa mojej skromnej mienky malo byť záležitosťou UI.

  • 8. 7. 2013 18:17

    j (neregistrovaný)

    To souhlas, ale proste je to tak jak to je, ze primo SQLko umi vracet datumy v ruznych formatech na prani ... a uplne stejne se chovaji desetinna cisla, kde z toho podle nastaveni vylezou tecky nebo carky. A to znam i aplikaci, kde se pri komunikaci pres XML vyplnuje zhruba nasledovne:


    [OBJEDNAVKA]
    [POLOZKA zbozi="sud" baleni="3,5"]4­.7[/POLOZKA]
    [/OBJEDNAVKA]

    Proste nejakou hlavu vymazanou by bylo treba strcit do 1/2coulovy vodovodni trubky ... zjevne by se tam vpohode vesla.

  • 8. 7. 2013 17:40

    ps (neregistrovaný)

    Ja tu neriešim variantu A, mne sa len nepáči varianta B a ani to nie s ohľadom na performance, ale kvalitu kódu. Ja som proste zástanca jednoduchosti a nepáči sa mi keď niekto rieši niečo na vrstvách na ktoré to nepatrí.

    No trochu sa ma dotklo keď si ma obvinil na základe tvojich dojmov že som nič poriadne neriešil :). Ja som veru nikoho konkrétneho neurážal. Ale keď vidím mnohých diskutujúch ktorým etika na fórach nič nehovorí, tak sa nad tým len pousmejem.

    Keby si mi radšej napísal ako v tvojich zásadných riešeniach postavených na M$SQL postupuješ keď nevieš aký je nastavený jazyk a aká je fáza mesiaca. Pretože ja som na podobný problém ešte nenarazil. Asi som príliš zásadový dátum vždy píšem ako YYYYMMDD alebo YYYY-MM-DDTHH:MM:SS (poprípade YYYY-MM-DD ale to len keď sa hrám v konzole a chcem aby to pekne vyzeralo, každopádne ako generovaný string z DB adaptéra by som to pre MSSQL nepoužil). Počul si už o ISO 8601 o ktorom už počuli aj súdruhovia v M$?

  • 8. 7. 2013 17:59

    j (neregistrovaný)

    Pouzivat muzes format jaky chces, potiz je v tom, ze ty jednoduse predem nevis, jak se rozhodne to M$ SQL ze ma/nema nastavenej jazyk/konverze. Pokud mas aplikaci + server naprosto ve svy moci, tak se sice da spolejhat na to, ze se to bude chovat porad stejne (dokud to neopatchujes), ale k databazi/serveru se vetsinou taky pripojujou nejaci klienti ... a u tech proste to, jak maji nastavenej jazyk neovlivnis. Navic prave v pripade widli je velmi zasadni rozdil, jestli jde o widle anglicke s ceskou lokalizaci nebo widle ceske ... a to na vsech urovnich (jak srv tak klient).

    A potom konverzi zajistuju tam, kde uz to mam ve sve moci - tedy klido na urovni SQL. Totiz ona bezpecnost/kon­zistence dat/... je o asi tak rad dulezitejsi, nez nejaka milisekunda.

    BTW: Spousta "webaru" pouzivajicich MySQL vubec netusi, jak (spravne) tu databazi pripojit, a pak se divej, ze maj potize s diakritikou, s hledanim ... a datumy, protoze vubec netusej, ze jsou 3 mista, kde to musi nastavit - a jedno z nich je trebas vlastni konexe do databaze, kde se prave spolejhaj na nejakou implicitni hodnotu ... o ktere vubec nevi ze existuje.

    (pro zajimavost, v pripade webu je treba znat nataveni databaze, nastaveni konexe a pak jeste poslat spravne hlavicky - jinak to nebude fungovat)

  • 8. 7. 2013 18:03

    belzebub (neregistrovaný)

    A mohl byste, misto zavadeni debaty jinam (ruzne formaty zapisu data), treba napsat variantu C, ktera by podle Vas byla spravne?

  • 8. 7. 2013 18:26

    j (neregistrovaný)

    Pokud vim, jeho predstava je, ze to ma vypadat takhle:


    SELECT
    FROM sales
    WHERE sale_date = '19700101';

    Coz bude sranda, az tam napisu '19700511' a pak se bude resit, jestli je to 11.5. nebo 5.11. ... nebot oboji je jiste mozne (a i ten vice imbecilni zapis - tedy YYYYDDMM sem uz videl - pouzivaj ho britove, podobne jako palce a stopy ...).

    Pokud tam je ta konverze, tak je zcela jasne, co tim pisatel minil a tudiz netreba resit, jak je zrovna nastaveny prostredi.

  • 8. 7. 2013 18:31

    ps (neregistrovaný)

    No myslel som si že to priamo vyplýva z toho čo som napísal, ale to môže povedať o sebe každý. Takže sa ospravedlňujem a skúsim ešte raz:
    Neodsudzujem autora že robí CONVERT, ja to ale nepovažujem za ideálne riešenie, ale ako nutné zlo (workaround), a úplne chápem že na niektorých serveroch sa to proste robiť musí. Kebyže Convert nebol potrebný, nikdy by developer nebol omylom napísal niečo ako Variant A (iba ak naschvál).

    V ideálnom svete by každý SQL server ktorý vie že sale_date je typu date/datetime pochopil

    SELECT FROM sales
    WHERE sale_date = 19700101

    ale nie som ortodoxný. Celkom by mi stačilo aby si každý výrobca SQL servera zvolil svoj formát, ktorý vie za každých okolností implicitne rozparsovať
    (napr. '19700101', '1970-01-01')

  • 8. 7. 2013 18:58

    Pavel Stěhule

    SQL bylo navrženo pro ruční zadávání, takže výrobci předpokládali, že uživatelé budou chtít zadávat a číst datumové typy dle svých národních zvyklostí - a s radostí jim to umožnili, a uživatelé to začali chtít. Navíc, v běžných programovacích jazycích chyběla jakákoliv podpora pro typ date, pro regulární výrazy, .. takže parsování stringů a operace s datumy na straně klienta byly dost obtížné, a bylo příjemné, když to db udělala za vás. Dost pozdě jim došlo, že to nebyl dobrý nápad, nicméně z důvodů zpětné kompatibility to už nešlo změnit. Když se podíváte do kódu Postgresu pro typ date, tak objevíte dost komplikovaný kód, kterého by se všichni rádi zbavili a podporovali jenom ANSI formát - 'YYYY-MM-DD', ale to nejde.

    Jinak způsob zápisu datumu jako celého čísla není šikovný. Totiž hrozí možná záměna s integrem - jednak hrozí riziko chyb typu

    WHERE sales_date = 1970-01-01

    což je samosebou něco jiného, než programátor očekával - a třeba pg nedovoluje implicitní konverzi mezi date a int.

  • 9. 7. 2013 10:47

    belzebub (neregistrovaný)

    Aha. Jedna se tedy o konflikt mezi Vasi predstavou "idealniho sveta" a realitou.

    To je opravdu nebezpecny pristup. Toto neni idealni svet, kazdy SQL server je trosku jiny a snaha psat reseni pro "idealni svet" nutne skonci spatne. A prestoze ja sam si casto preji, aby ruzne technologie pracovaly trosku "lepe" (rozumejte: tak jak JA si myslim ze by to bylo lepe), tyto uvahy vedou pouze k frustraci a stresu.

    Je urcite dobre vedet jak by slo neco udelat lepe (a pak to tak udelat, pokud clovek dostane prilezitost), ale kritizovat SPRAVNE a FUNKCNI reseni, protoze by v "idealnim svete" mohlo byt jine, je velmi spatny pristup.

  • 9. 7. 2013 16:28

    Nezmar (neregistrovaný)

    Implicitní konverzi je obecně lepší se vyhnout. Navíc třeba konkrétne u Oracle nevíte co vlastně bude konvertovat.

    Dotaz

    select * from tabulka where sloupcec_typu_strin­g=1;

    proběhne tak, že se pokusí zkonverovat hodnoty soupečku na číslo (a přitom samozřejmě většinou spadne)

  • 9. 7. 2013 16:35

    Ivan (neregistrovaný)

    Anebo tenhle spek:
    select * from t where a between :b and :c

    kde a je DATE, :B, :C jsou stringy anebo cisla. Jak se to nakonec porovna?

  • 9. 7. 2013 18:43

    lt (neregistrovaný)

    Uvedeny priklad a konverzia to_date('1970-01-01', 'YYYY-MM-DD') je uplne spravna a presne takto sa to ma robit. Pretoze neexistuje, aby sa to ponechalo na implicitnu konverziu. Naopak, komukolvek, kto ponechava konverziu na DATE na system a robi implicitnu konverziu, by som lamal ruky. Jedine co by som vylepsil je na to_date('19700101', 'YYYYMMDD') .