[DB2] Problem z 'like' przy nullowych kolumnach.
Jan Słupicki - 07-02-2006 16:43
[DB2] Problem z 'like' przy nullowych kolumnach.
Wyszukuję rekordy przy pomocy 'like' ale badana kolumna może mieć nulle. W takim przypadku rekord może być zaakceptowany tylko wtedy gdy wartość po 'like' to dokładnie '%'. Zrobiłem tak: value(kolumna,'%') like parametr i to działa ok. Martwię się o wydajność bo pewnie nie będzie działać indeks na kolumnie. Nie znalazłem w helpie możliwości tworzenia indeksów funkcyjnych w DB2 (może coś przeoczyłem). Niestety nie mogę zrobić kontrukcji: kolumna like parametr or (kolumna is null and '%'=parametr) bo parametr jest podwiązywany w JDBC i wywala mi błąd -302. Jak to zrobić aby działało maksymalnie szybko ?
-- Jan Słupicki
Filip Sielimowicz - 13-02-2006 10:31
Użytkownik "Jan Słupicki" <j.slupicki@provider.pl> napisał w wiadomości news:dsa9br$a8h$1@atena.e-wro.net... > Wyszukuję rekordy przy pomocy 'like' ale badana kolumna może mieć nulle. > W takim przypadku rekord może być zaakceptowany tylko wtedy gdy > wartość po 'like' to dokładnie '%'. > Zrobiłem tak: > value(kolumna,'%') like parametr > i to działa ok. Martwię się o wydajność bo pewnie nie będzie działać > indeks > na kolumnie. Nie znalazłem w helpie możliwości tworzenia indeksów > funkcyjnych > w DB2 (może coś przeoczyłem). Niestety nie mogę zrobić kontrukcji: > kolumna like parametr or (kolumna is null and '%'=parametr) > bo parametr jest podwiązywany w JDBC i wywala mi błąd -302. > Jak to zrobić aby działało maksymalnie szybko ?
W db2 odpowiednikiem indeksów funkcyjnych jest kolumna wyliczana z założonym indeksem.
Przykład kopiuję z comp.databases.ibm-db2:
CREATE TABLE T(c1 varchar(10), uc1 GENERATED ALWAYS AS (UPPER(c1))); CREATE INDEX i1 ON T(uc1); INSERT INTO T(c1) VALUES ('hello'), ('world'); SELECT c1 FROM T WHERE UPPER(c1) = 'HELLO';
Powyższe realizuje indeks funkcyjny na funkcji UPPER(c1). Proszę zauważyć, że w ostatnim zapytaniu nie odwołujemy się do kolumny uc1. DB2 potrafi inteligentnie skojarzyć wyrażenie UPPER(c1) ze zdefiniowanym identycznie polem wyliczanym i użyje indeksu.
Gdyby ten kierunek na nic się nie zdał (nie podoba mi się ta funkcja value z dwoma parametrami, ale nie analizuję tego glębiej), to być może uda się przynajmniej rozbić ten błąd -302. Proszę spojrzeć na podane niżej wyrażenie:
kolumna like :param or (kolumna is null and cast('%' as varchar(100))=cast(:param as varchar(100)))
W każdym bądź razie u mnie to działa, pozostaje tylko rozważyć cast na inny typ niż varchar(100).
Pozdrowienia ! Filip Sielimowicz http://panda.bg.univ.gda.pl/~sielim/fractal/index.htm
Jan Słupicki - 13-02-2006 10:32
> W db2 odpowiednikiem indeksów funkcyjnych jest kolumna wyliczana z > założonym indeksem. > > Przykład kopiuję z comp.databases.ibm-db2: > > CREATE TABLE T(c1 varchar(10), uc1 GENERATED ALWAYS AS (UPPER(c1))); > CREATE INDEX i1 ON T(uc1); > INSERT INTO T(c1) VALUES ('hello'), ('world'); > SELECT c1 FROM T WHERE UPPER(c1) = 'HELLO'; > > Powyższe realizuje indeks funkcyjny na funkcji UPPER(c1). > Proszę zauważyć, że w ostatnim zapytaniu nie odwołujemy się do > kolumny uc1. DB2 potrafi inteligentnie skojarzyć wyrażenie > UPPER(c1) ze zdefiniowanym identycznie polem wyliczanym > i użyje indeksu.
Trochę to dziwne ale jeśli będzie działać ...
> Gdyby ten kierunek na nic się nie zdał (nie podoba mi się ta funkcja > value z dwoma parametrami, ale nie analizuję tego glębiej), to > być może uda się przynajmniej rozbić ten błąd -302. Proszę spojrzeć > na podane niżej wyrażenie: > > kolumna like :param or > (kolumna is null and cast('%' as varchar(100))=cast(:param as > varchar(100))) > > W każdym bądź razie u mnie to działa, pozostaje tylko rozważyć cast na > inny typ > niż varchar(100).
Dzięki serdeczne.
-- Jan Słupicki
Filip Sielimowicz - 15-02-2006 09:43
Użytkownik "Jan Słupicki" <j.slupicki@provider.pl> napisał w wiadomości news:dsphfl$n75$1@atena.e-wro.net... >> W db2 odpowiednikiem indeksów funkcyjnych jest kolumna wyliczana z >> założonym indeksem. >> >> Przykład kopiuję z comp.databases.ibm-db2: >> >> CREATE TABLE T(c1 varchar(10), uc1 GENERATED ALWAYS AS (UPPER(c1))); >> CREATE INDEX i1 ON T(uc1); >> INSERT INTO T(c1) VALUES ('hello'), ('world'); >> SELECT c1 FROM T WHERE UPPER(c1) = 'HELLO'; >> >> Powyższe realizuje indeks funkcyjny na funkcji UPPER(c1). >> Proszę zauważyć, że w ostatnim zapytaniu nie odwołujemy się do >> kolumny uc1. DB2 potrafi inteligentnie skojarzyć wyrażenie >> UPPER(c1) ze zdefiniowanym identycznie polem wyliczanym >> i użyje indeksu. > > Trochę to dziwne ale jeśli będzie działać ... Dziwne, nie dziwne - funkcjonalnie jest to to samo. Zakładanie pól wyliczanych i na nich indeksów to standardowy sposób rozwiązywania takich problemów w bazach "bez bajerów" (np. intensywnie ćwiczyłem temat w bazie InterBase). Indeks funkcyjny, z którym spotkałem się tylko na postgresie, nic nowego tu nie wnosi, poza tym, że pozwala zachować większy porządek w tabeli - nie każe tworzyć i używać w zapytaniach egzotycznych kolumn. Czyli jest bardziej elegancki. Twórcy db2 nie zdecydowali się na całkowite wyeliminowanie tych kolumn, ale postarali się, by w zapytaniach nie trzeba było już o nich pamiętać - tak jak w indeksie funkcyjnym, też możemy używać bezpośrednio wyrażeń funkcyjnych.
Zapewne są też różnice w wewnętrznej reprezentacji, zajętości pamięci, ale to już nas mało interesuje.
Jan Słupicki - 20-02-2006 14:08
>> Trochę to dziwne ale jeśli będzie działać ... > Dziwne, nie dziwne - funkcjonalnie jest to to samo. > Zakładanie pól wyliczanych i na nich indeksów to standardowy > sposób rozwiązywania takich problemów w bazach "bez bajerów" > (np. intensywnie ćwiczyłem temat w bazie InterBase). > Indeks funkcyjny, z którym spotkałem się tylko na postgresie, > nic nowego tu nie wnosi, poza tym, że pozwala zachować większy > porządek w tabeli - nie każe tworzyć i używać w zapytaniach > egzotycznych kolumn. Czyli jest bardziej elegancki. Twórcy db2 > nie zdecydowali się na całkowite wyeliminowanie tych kolumn, > ale postarali się, by w zapytaniach nie trzeba było już o nich > pamiętać - tak jak w indeksie funkcyjnym, też możemy używać > bezpośrednio wyrażeń funkcyjnych. > > Zapewne są też różnice w wewnętrznej reprezentacji, zajętości pamięci, > ale to już nas mało interesuje.
Wcześniej pracowałem na Postgresie i Oraclu. Tam używałem oczywiście indeksów funkcyjnych. Pierwszy raz widzę kolumny generowane automatycznie i dlatego wydało mi się to trochę dziwaczne. Po zastanowieniu mechanizm ten wydaje mi się dość atrakcyjny.
Co do rozwiązania mojego problemu to użyłem metody drugiej czyli z CAST w zapytaniu - działa ok. Dzięki.
-- Jan Słupicki
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[MSSQL2000] Problem z =?ISO-8859-2?Q?tabel=B1/indeksem/zapytanie?==?ISO-8859-2?Q?m_czy_b=B3=B1d_w_bazie_danych=2E=2E=2E?=
mysql i mysql-front, problem
String line; if (line=="cos"){...}....problem
Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?=
[postgres] Problem z =?ISO-8859-2?Q?zmian=B1_struktury_i_z?==?ISO-8859-2?Q?ale=BFno=B6ciami=2E?=
[oracle] =?ISO-8859-2?Q?zmia=BFd=BFony_przez_problem=3A_za?==?ISO-8859-2?Q?pytanie_do_hierarchi?=
Problem z wartościami w MySQL :( [ MySQL and ASP and VBScript ]
[PGSQL] czy ktos mial problemy z initdb pgsql 8.1 ?
[MySQL] Problem z zapisem danych w bazie danych
Problem z mysql - can't connect to MySQL/nietypowo...
zanotowane.pldoc.pisz.plpdf.pisz.plponland.htw.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|