Rafał Juszkiewicz

Rafał Juszkiewicz Inżynier
Oprogramowania

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Czesc,
zastanawiam sie jakie indeksy utworzyc dla tabel bad_sector oraz total_sector aby nastepujace zapytanie wykonywalo sie optymalnie:

SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a, TOTAL_SECTOR b
WHERE a.REGION = 'warszawa'
AND b.REGION = a.REGION
AND b.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND DATE_FORMAT( a.DATE, '%Y-%m-%d' ) = b.DATE
AND b.DATE LIKE '2008-07%'

Z gory dziekuje za odpowiedz

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Rafał Juszkiewicz:
Czesc,
zastanawiam sie jakie indeksy utworzyc dla tabel bad_sector oraz total_sector aby nastepujace zapytanie wykonywalo sie optymalnie:

SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a, TOTAL_SECTOR b
WHERE a.REGION = 'warszawa'
AND b.REGION = a.REGION
AND b.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND DATE_FORMAT( a.DATE, '%Y-%m-%d' ) = b.DATE
AND b.DATE LIKE '2008-07%'
Jaka baza danych ?
Ogólnie to się robi tak, że podajesz pełen sposób wykonywania zapytania - np. explain analyze pod postgresqlem i wtedy coś można powiedzieć. Inaczej to jest zgadywanie / ogólne uwagi...

Na bad_sector postawiłbym klucz na region, typ_sieci, DATE_FORMAT( a.DATE, '%Y-%m-%d') na total_sector podobnie, na DATE klucz prefixowy...

Czy jest jakiś konkretny powód, że data w total_sector jest ciągiem znaków? Większość serwerów dobrze optymalizuje between - i daje to lepsze efekty.

Czy w grę wchodzi tylko dodanie indeksów, czy można zmienić zapytanie?

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

;) aa rozmyśliłem się..Rafał Wardas edytował(a) ten post dnia 31.07.08 o godzinie 12:06

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Najwięcej byś uzyskał gdybyś jednak popracował nad tymi datami.
Albo:
a) dodać do TOTAL_SECTOR zwykłą datę
albo
b) w BAD_SECTOR zmienić datę na format tekstowy

W obu przypadkach dodajesz co najmniej jeden indeks - TOTAL_SECTOR.date (może zawierać więcej pól).

W przypadku (b) także indeks na BAD_SECTOR.date

Oczywiście można to rozbudowywać dalej - aby tylko nie przesadzić z liczbą pól.

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

to nie MS ale generalnie pewnie jest podobnie
po lewej stronie nie powinno być wyliczanek
wiec na poczatek zamien tego whera zeby nie było DATE_FORMAT( a.DATE, '%Y-%m-%d' ) = b.DATE
czy date indeksować ... może ale napewno region
Wojciech Nowak

Wojciech Nowak Konsultant Systemów
Bankowych | Analityk
Systemowy

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

jaka to baza danych?

AND DATE_FORMAT( a.DATE, '%Y-%m-%d' ) = b.DATE
AND b.DATE LIKE '2008-07%'

myślę, że powyższe spowalnia, natomiast index musi być na kluczach w warunku złączenia

wnWojciech Nowak edytował(a) ten post dnia 31.07.08 o godzinie 12:30
Rafał Juszkiewicz

Rafał Juszkiewicz Inżynier
Oprogramowania

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Baza danych MySQL 5.0
Liczba rekordow:
bad_sector : 400 000
total_sector : 2000

Daty w obu tabelach:
bad_sector.date jest typu datetime
total_sector.date jest typu date
Stad to wyrazenie DATE_FORMAT( a.DATE, '%Y-%m-%d' ).

klucze w warunku zlaczenia to klucze o malej gestosci:
typ_sieci - 2 mozliwosci
region - 4 mozliwosci

Dodajac indeksy na te pola w obu tabelach, nie przyspiesza, a nawet wydluza zapytanie.
Dodajac indeks na date zszedlem z 10s do 5s.
Piotr Czeczko

Piotr Czeczko Technical Director

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

może moja sugestia bedzie trywialna, ale czy sprawdzales plan zapytania czy idzie po wlasciwych indeksach?

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Rafał Juszkiewicz:
Baza danych MySQL 5.0
Liczba rekordow:
bad_sector : 400 000
total_sector : 2000

Daty w obu tabelach:
bad_sector.date jest typu datetime
total_sector.date jest typu date
Stad to wyrazenie DATE_FORMAT( a.DATE, '%Y-%m-%d' ).

klucze w warunku zlaczenia to klucze o malej gestosci:
typ_sieci - 2 mozliwosci
region - 4 mozliwosci

Przy takiej liczebności indeks na te pola może w ogóle nie być brany pod uwagę. Dlatego data jest lepszym, zgrubnym rozwiązaniem.
W swojej sugestii załozyłem, że typy sieci czy regiony nie przybywają masowo w czasie.
Marcin Czajczyk

Marcin Czajczyk Project manager

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

jest tutaj niekonsekwencja typów danych - jedną z dat przerobiłbym na typ drugiej, tak by były takie same, a następnie stworzyłbym indeks na nich. nie wiem jak to jest w MySQL, ale w oraclu użyłbym na końcu
zamiast
b.DATE LIKE '2008-07%'
użyłbym
b.DATE >= '2008-07-01'
and b.DATE < '2008-08-01'

nie wiem czy tu będzie to odpowiednie, ale powinno być :)
Izabela Korzińska

Izabela Korzińska Architekt /
Developer ETL/TEam
Leader, Roche Polska

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Nie wiem, jak jest w MySQL, ale jeśli możesz stworzyć indeks funkcyjny tak, jak w Oracle, to spróbuj na tabeli BAD_SECTOR założyć taki:
1. region,
2. typ_sieci,
3. trunc(date)

i wtedy zamiast Twego zapytania napisałabym:
SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a join TOTAL_SECTOR b on
(
a.REGION = b.'warszawa'
AND b.REGION = a.REGION
AND a.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND trunc( a.DATE) = b.DATE
AND b.DATE between '2008-07-01' and '2008-07-31'
)
Mam nadzieję, że w MySQL jest funkcja "trunc" :)

pozdr
Iza

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Izabela Korzińska:
Nie wiem, jak jest w MySQL, ale jeśli możesz stworzyć indeks funkcyjny tak, jak w Oracle, to spróbuj na tabeli BAD_SECTOR założyć taki:
1. region,
2. typ_sieci,

Tu się nie opłaca ;)
3. trunc(date)

i wtedy zamiast Twego zapytania napisałabym:
SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a join TOTAL_SECTOR b on
(
a.REGION = b.'warszawa'
AND b.REGION = a.REGION
AND a.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND trunc( a.DATE) = b.DATE
AND b.DATE between '2008-07-01' and '2008-07-31'

BETWEEN ma zakres (a, b) nie <a,b>
)
Mam nadzieję, że w MySQL jest funkcja "trunc" :)

pozdr
Iza

Dziwi mnie wasze porównywanie daty reprezentowanej przez liczbę jako stringa.

Pozdrawiam ;)Rafał Wardas edytował(a) ten post dnia 01.08.08 o godzinie 23:18
Izabela Korzińska

Izabela Korzińska Architekt /
Developer ETL/TEam
Leader, Roche Polska

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Rafał Wardas:
Izabela Korzińska:
Nie wiem, jak jest w MySQL, ale jeśli możesz stworzyć indeks funkcyjny tak, jak w Oracle, to spróbuj na tabeli BAD_SECTOR założyć taki:
1. region,
2. typ_sieci,

Tu się nie opłaca ;)

No to 2-poziomowy, skoro się nie opłaca.
3. trunc(date)

i wtedy zamiast Twego zapytania napisałabym:
SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a join TOTAL_SECTOR b on
(
a.REGION = b.'warszawa'
AND b.REGION = a.REGION
AND a.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND trunc( a.DATE) = b.DATE
AND b.DATE between '2008-07-01' and '2008-07-31'

BETWEEN ma zakres (a, b) nie <a,b>

Bzdura. Już myślałam, że może w MySQL jest inaczej, ale nie: http://dev.mysql.com/doc/refman/5.0/en/comparison-oper...
)
Mam nadzieję, że w MySQL jest funkcja "trunc" :)

pozdr
Iza

Dziwi mnie wasze porównywanie daty reprezentowanej przez liczbę jako stringa.

Napisałam, to tak, jak w ORACLE, a tam się podaje daty w poj. cudzysłowie, bo inaczej ORACLE Cię nie zrozumie. Nawet lepiej jest podać datę wewnątrz funkcji to_date, bo ta, podana w cudzysłowie może być w innym formacie, niż data wybrana w ustawieniach klienta. I nawet wewnątrz funkcji to_date datę podajesz w cudzysłowie :)

pozdr
Iza
Jerzy Paweł Pielich

Jerzy Paweł Pielich Właściciel, JPP Info

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Rafał Juszkiewicz:
Czesc,
zastanawiam sie jakie indeksy utworzyc dla tabel bad_sector oraz total_sector aby nastepujace zapytanie wykonywalo sie optymalnie:

SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a, TOTAL_SECTOR b
WHERE a.REGION = 'warszawa'
AND b.REGION = a.REGION
AND b.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND DATE_FORMAT( a.DATE, '%Y-%m-%d' ) = b.DATE
AND b.DATE LIKE '2008-07%'

Z gory dziekuje za odpowiedz


Ogólnie zasada jest taka załóż klucz na
polach klauzuli Where i najlepiej w takiej samej
kolejności jak w Where.
Ćwiczyłem to , to działa.

konto usunięte

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Izabela Korzińska:
Rafał Wardas:
Izabela Korzińska:
Nie wiem, jak jest w MySQL, ale jeśli możesz stworzyć indeks funkcyjny tak, jak w Oracle, to spróbuj na tabeli BAD_SECTOR założyć taki:
1. region,
2. typ_sieci,

Tu się nie opłaca ;)

No to 2-poziomowy, skoro się nie opłaca.
3. trunc(date)

i wtedy zamiast Twego zapytania napisałabym:
SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a join TOTAL_SECTOR b on
(
a.REGION = b.'warszawa'
AND b.REGION = a.REGION
AND a.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND trunc( a.DATE) = b.DATE
AND b.DATE between '2008-07-01' and '2008-07-31'

BETWEEN ma zakres (a, b) nie <a,b>

Bzdura. Już myślałam, że może w MySQL jest inaczej, ale nie: http://dev.mysql.com/doc/refman/5.0/en/comparison-oper...
No ok ;) przyznaję rację, robiłem kiedyś wyprowadzanie błędów na zewnątrz procedury i sypało mi się na końcu, zaraz obok BETWEEN, to źle sobie zakodowałem...
)
Mam nadzieję, że w MySQL jest funkcja "trunc" :)

pozdr
Iza

Dziwi mnie wasze porównywanie daty reprezentowanej przez liczbę jako stringa.

Napisałam, to tak, jak w ORACLE, a tam się podaje daty w poj. cudzysłowie, bo inaczej ORACLE Cię nie zrozumie. Nawet lepiej jest podać datę wewnątrz funkcji to_date, bo ta, podana w cudzysłowie może być w innym formacie, niż data wybrana w ustawieniach klienta. I nawet wewnątrz funkcji to_date datę podajesz w cudzysłowie :)

pozdr
Iza
Marcin Czajczyk

Marcin Czajczyk Project manager

Temat: Jakie indeksy utworzyc dla tabel przy nastepujacym...

Rafał Wardas:
Izabela Korzińska:
Nie wiem, jak jest w MySQL, ale jeśli możesz stworzyć indeks funkcyjny tak, jak w Oracle, to spróbuj na tabeli BAD_SECTOR założyć taki:
1. region,
2. typ_sieci,

Tu się nie opłaca ;)
3. trunc(date)

To jest jeden index - 3 poziomowy - opłaca się jak jest duże rozdrobnienie i szukamy małej ilości. jak jest inaczej to trzeba sprawdzić czy zyskujemy czy też nie...

i wtedy zamiast Twego zapytania napisałabym:
SELECT SUM( a.number_of_sectors * a.duration / b.SUM )
FROM BAD_SECTOR a join TOTAL_SECTOR b on
(
a.REGION = b.'warszawa'
AND b.REGION = a.REGION
AND a.TYP_SIECI = '2G'
AND a.TYP_SIECI = b.TYP_SIECI
AND trunc( a.DATE) = b.DATE
AND b.DATE between '2008-07-01' and '2008-07-31'

BETWEEN ma zakres (a, b) nie <a,b>

To już wyjaśnione - jest <a,b> :)
)
Mam nadzieję, że w MySQL jest funkcja "trunc" :)

pozdr
Iza

Dziwi mnie wasze porównywanie daty reprezentowanej przez liczbę jako stringa.

Oczywiście to jest skrót - jeżeli w parametrach oracle domyślna data jest prezentowana w postaci YYYY-MM-DD to zadziała, jak inaczej, to nie. Najlepiej zawsze użyć funckji to_date - daje 100% pewność. A napisałem tak, ponieważ tak jest szybciej i bardziej czytelnie - ja często pomijam to_date()...

Pozdrawiam ;)

Pozdrawiam



Wyślij zaproszenie do