optymalizacja zapytania UPDATE według 2 tabel

1

Witam serdecznie,

chciałabym zopymalizować zapytania SQL, działają mi ale ilość ich spowalnia działanie aplikacji. Chciałabym je wszystkie razem połączyć. Wykonanie jednego dużego zapytania , a wykonie oddzielne ich wszystkich wydłuża wykonanie modyfikacji jednej kolumny.
Moje zapytania przedsawiają się nasępująco (wersja pod Access):

stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 'brak: kolumna_1; '
WHERE ( statystyka.kolumna='kolumna_1' AND statystyka.tabela='tabela_A' ) AND tabela_A.opis_bledow = 'brak: kolumna_1; ';");

stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 'brak: kolumna_2; '
WHERE ( statystyka.kolumna='kolumna_2' AND statystyka.tabela='tabela_A' ) AND tabela_A.opis_bledow = 'brak: kolumna_2; ';");
	
	
stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 'brak: kolumna_3; '
WHERE ( statystyka.kolumna='kolumna_3' AND statystyka.tabela='tabela_A' ) AND tabela_A.opis_bledow = 'brak: kolumna_3; ';");

tabela TABELA_A przedstawia się następująco

ID_TABELA_A OPIS_BLEDOW KOLUMNA_1 KOLUMNA_2 KOLUMNA_3
1 brak: kolumna_1; brak: kolumna_3; - b -
2 brak: kolumna_3; a b -
3 brak: kolumna_1; - b c

tabela satystyka przedsawia się w następujący sposób:

blad kolumna tabela ilosc
kolumna_1 tabela_A
kolumna_2 tabela_A
kolumna_3 tabela_A

wersja pod Oracle:

UPDATE  statystyka 
	SET statystyka.blad ='brak: kolumna_1; ' 
		WHERE  ( statystyka.kolumna='kolumna_1' AND statystyka.tabela='tabela_A' ) AND 
			EXISTS ( 
				SELECT 1 
				FROM tabela_A 
				WHERE tabela_A.opis_bledow like '%kolumna_1;%'
			);
			
UPDATE  statystyka 
	SET statystyka.blad ='brak: kolumna_2; ' 
		WHERE  ( statystyka.kolumna='kolumna_2' AND statystyka.tabela='tabela_A' ) AND 
			EXISTS ( 
				SELECT 1 
				FROM tabela_A 
				WHERE tabela_A.opis_bledow like '%kolumna_2;%'
			);
			
UPDATE  statystyka 
	SET statystyka.blad ='brak: kolumna_3; ' 
		WHERE  ( statystyka.kolumna='kolumna_3' AND statystyka.tabela='tabela_A' ) AND 
			EXISTS ( 
				SELECT 1 
				FROM tabela_A 
				WHERE tabela_A.opis_bledow like '%kolumna_3;%'
			);

Chciałabym zrobić tak, aby jednym zapytaniem SQL uzupełniało mi w tabeli *statystyka * , 3 wartości :
statystyka.blad ='brak: kolumna_1; '
gdy dla tabeli *tabela_A * w kolumnie *OPIS_BLEDOW * jeśli będzie wartość 'brak: kolumna_1; '

statystyka.blad ='brak: kolumna_2; '
gdy dla tabeli *tabela_A * w kolumnie OPIS_BLEDOW jeśli będzie wartość 'brak: kolumna_2; '

statystyka.blad ='brak: kolumna_3; '
gdy dla tabeli tabela_A w kolumnie OPIS_BLEDOW jeśli będzie wartość 'brak: kolumna_3; '

Próbowałam wykonać takie sprawdzenie (wersja pod Access) , ale mi to działanie nie działało prawidłowo :( :

stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 
IIf (statystyka.kolumna ='kolumna_1' AND tabela_A.opis_bledow  = '*kolumna_1*', ''  'brak: kolumna_1; ') & 
IIf (statystyka.kolumna ='kolumna_2' AND tabela_A.opis_bledow  = '*kolumna_2*', ''  'brak: kolumna_2; ') & 
IIf (statystyka.kolumna ='kolumna_3' AND tabela_A.opis_bledow  = '*kolumna_3*', ''  'brak: kolumna_3; ') 
WHERE  statystyka.tabela='tabela_A'; ");

bardzo uprzejmie prosiłabym o wskazówkę pod Oracle, ( do access właśnie mi się skończyła licencja :( )
Jak wykonać jednym zapytaniem, edycje w tabeli *statystyka * dla kolumny *blad * Jeśli znajdzie np wartość brak: kolumna_1; w kolumnie OPIS_BLEDOW i zapisało tą informację dla kolumny blad * w postaci * 'brak: kolumna_1; '

0

Domyślam się że tablea 'tabela_a' jest duża (tysiące - miliony rekordów) - zgadza się ?
Jeśli tak, to nie sądzę że zmiana 3 pytań na jedno wiele tu pomoże.
Szkopuł tkwi w błednie zaprojektowanej tabeli 'tabela_a' - kłania się teoria baz danych,
konkretnie postacie normalne --> http://pl.wikipedia.org/wiki/Normalizacja_bazy_danych
Pierwsza postać normalna 1NF mówi: składowe w każdej krotce muszą być atomowe (aby nie dały się podzielić na mniejsze wartości).
Pole 'opis_bledow' w tej tabeli nie jest atomowe - może zawierać informacje o 1,2,3 lub więcej "błędach".
W związku z tym przy każdym dostępie do tej kolumny trzeba "wycinać" z tej kolumny potrzebne informacje konstrukcjami takimi jak LIKE '%xxx%'
albo substr( xxx, y, z).
Z tego powodu:

  1. pożera to niepotrzebnie cykle procesora na "wyciąganie" z kolumny potrzebnych informacji
  2. wymaga zawsze przeglądu całej tabeli (full table scan) - nie da się np. zastosować indeksów do przyspieszenia zapytań.
0
kordirko napisał(a)

Domyślam się że tablea 'tabela_a' jest duża (tysiące - miliony rekordów) - zgadza się ?
tak

kordirko napisał(a)

Jeśli tak, to nie sądzę że zmiana 3 pytań na jedno wiele tu pomoże.
nałożenie indexów na te kolumny może jeszcze pomoże, ale już je mam :)

kordirko napisał(a)

Szkopuł tkwi w błednie zaprojektowanej tabeli 'tabela_a' - kłania się teoria baz danych,
konkretnie postacie normalne --> http://pl.wikipedia.org/wiki/Normalizacja_bazy_danych
Pierwsza postać normalna 1NF mówi: składowe w każdej krotce muszą być atomowe (aby nie dały się podzielić na mniejsze wartości).
Pole 'opis_bledow' w tej tabeli nie jest atomowe - może zawierać informacje o 1,2,3 lub więcej "błędach".
W związku z tym przy każdym dostępie do tej kolumny trzeba "wycinać" z tej kolumny potrzebne informacje konstrukcjami takimi jak LIKE '%xxx%'
albo substr( xxx, y, z).
Z tego powodu:

  1. pożera to niepotrzebnie cykle procesora na "wyciąganie" z kolumny potrzebnych informacji
  2. wymaga zawsze przeglądu całej tabeli (full table scan) - nie da się np. zastosować indeksów do przyspieszenia zapytań.
    wydaje mi się, że rozumiem
0

Jak jest indeks, to o tyle pomoże, że oracle będzie robił full scan indeksu,
a nie całej tabeli, przy czym dajel fullscan .

Takie pojedyńcze zapytanie mogłoby wyglądać np. tak
[code]
UPDATE statystyka
SET blad = case kolumna
when 'kolumna_1' then 'brak: koluma 1'
when 'kolumna_2' then 'brak: kolmna 2'
when 'kolumna_3' then 'brak: kolmnaa 3'
end
WHERE kolumna IN (
SELECT distinct kolumna
from tabela_a a
join
(
select 'kolumna_1' kolumna from dual union all
select 'kolumna_2' from dual union all
select 'kolumna_3' from dual
) x
ON a.opis_bledow like '%' || x.kolumna || '%'
) AND tabela = 'tabela A'
[/code]

A tak przy okazji - co te query ma liczyć, jakie jest wymaganie biznesowe ?

0

ehh zapytania pod Access nie chcą działać :( :( :(

ani te:

UPDATE  statystyka 
        SET statystyka.blad ='brak: kolumna_3; ' 
                WHERE  ( statystyka.kolumna='kolumna_3' AND statystyka.tabela='tabela_A' ) AND 
                        EXISTS ( 
                                SELECT 1 
                                FROM tabela_A 
                                WHERE tabela_A.opis_bledow LIKE '*kolumna_3;*'
                    );

ani te:

stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 'brak: kolumna_3; '
WHERE ( statystyka.kolumna='kolumna_3' AND statystyka.tabela='tabela_A' ) AND tabela_A.opis_bledow like '*brak: kolumna_3; *';");

ani te:

stmt.executeUpdate("UPDATE tabela_A, statystyka SET statystyka.blad = 'brak: kolumna_3; '
WHERE ( statystyka.kolumna='kolumna_3' AND statystyka.tabela='tabela_A' ) AND tabela_A.opis_bledow = '*brak: kolumna_3; *';");

Chciałabym aby dla poniższej tabelki :

tabela TABELA_A przedstawia się następująco

ID_TABELA_A OPIS_BLEDOW KOLUMNA_1 KOLUMNA_2 KOLUMNA_3
1 brak: kolumna_1; brak: kolumna_3; - b -
2 brak: kolumna_1; a b -
3 brak: kolumna_2; - b c

wyszukało mi z kolumny OPIS_BLEDOW wartość brak: kolumna_3; pod Oracle działa, ale już pod Access nie chce :( :( :(

1

udało mi się rozwiązać :) :) :) Skorzystałam z metody contains

java.sql.Statement stmt2 = conn_kasia.createStatement();
String query2 = "SELECT OPIS_BLEDOW FROM 'tabela_A' ;";
ResultSet rs2 = stmt2.executeQuery(query2);

while (rs2.next()) {
   try {
        String Status_Desc = rs2.getString("OPIS_BLEDOW");
        stmt2 = conn_kasia.createStatement();
          if (OPIS_BLEDOW.contains("brak: kolumna_1;")) {
              stmt2.executeUpdate("UPDATE  statystyka SET statystyka.blad = 'brak: kolumna_1;' WHERE statystyka.kolumna='kolumna_1' AND statystyka.tabela='tabela_A' ;");
          }

          if (OPIS_BLEDOW.contains("brak: kolumna_2;")) {
              stmt2.executeUpdate("UPDATE  statystyka SET statystyka.blad = 'brak: kolumna_2;' WHERE statystyka.kolumna='kolumna_2' AND statystyka.tabela='tabela_A';");
         }


      } catch (Exception e) {
            e.printStackTrace();
      }
}

Czeka mnie jeszcze optymalizacja :) :) :) :) :)

aaaa jeszcze policzenie ile jest wystąpień np brak: kolumna_2 w kolumnie OPIS_BLEDOW :) :) :)

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