2012-03-14 11 views
6

Mam stolik z 300 000 rekordów. W tej tabeli mają duplicae wierszy i chcę zaktualizować kolumny "flagę"Jak mogę zoptymalizować zapytanie MySQL o aktualizację?

TABLE

------------------------------------ 
|number | flag | ... more column ...| 
------------------------------------ 
|ABCD | 0 | ...................| 
|ABCD | 0 | ...................| 
|ABCD | 0 | ...................| 
|BCDE | 0 | ...................| 
|BCDE | 0 | ...................| 

używam tej kwerendy do aktualizacji "Flag" kolumna:

UPDATE table i 
INNER JOIN (SELECT number FROM table 
      GROUP BY number HAVING count(number) > 1) i2 
ON i.number = i2.number 
SET i.flag = '1' 

Ta kwerenda działa bardzo bardzo powoli (więcej 600 sekund) dla tego 300 000 rekordów.

Jak zoptymalizować to zapytanie?

STRUKTURA moim stole

CREATE TABLE IF NOT EXISTS `inv` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `pn` varchar(10) NOT NULL COMMENT 'Part Number', 
    `qty` int(5) NOT NULL, 
    `qty_old` int(5) NOT NULL, 
    `flag_qty` tinyint(1) NOT NULL, 
    `name` varchar(60) NOT NULL, 
    `vid` int(11) NOT NULL , 
    `flag_d` tinyint(1) NOT NULL , 
    `flag_u` tinyint(1) NOT NULL , 
    `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`), 
    KEY `pn` (`pn`), 
    KEY `name` (`name`), 
    KEY `vid` (`vid`), 
    KEY `pn_2` (`pn`), 
    KEY `flag_qty` (`flag_qty`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=0 ; 

Jeśli "nazwa" jest powielać Chcę zaktualizować flag_qty

+0

Jaka jest struktura tabeli? Czy na tej tabeli dostępny jest klucz podstawowy? – nnichols

+1

Jaki jest cel ustawienia tej flagi? Czy robisz dalsze przetwarzanie na podstawie tej flagi? – nnichols

+0

Celem tej flagi jest JEŻELI w tabeli zduplikowane wiersze tej flagi wynosi 1. Następnie chcę utworzyć tabelę z duplikatami wierszy i usunąć te wiersze z głównej tabeli. – dido

Odpowiedz

2

Jeżeli nie masz jeszcze indeksu na number należy dodać jeden -

CREATE INDEX table_number ON table (number); 

UPDATE Spróbuj tego -

UPDATE inv t1 
INNER JOIN inv t2 
    ON t1.name = t2.name 
    AND t1.id <> t2.id 
SET t1.flag_qty = 1; 

Można utworzyć tabelę z zaledwie duplikatów poprzez wybranie dane te są wprowadzane bezpośrednio do innej tabeli zamiast najpierw aktualizować tę flagę.

INSERT INTO duplicate_invs 
SELECT DISTINCT inv1.* 
FROM inv AS inv1 
INNER JOIN inv AS inv2 
    ON inv1.name = inv2.name 
    AND inv1.id < inv2.id 

Jeśli można wyjaśnić logikę, dla których wiersze zostaną usunięte z inv tabeli może się okazać, że cały proces może odbywać się w jednym etapie.

+0

numer kolumny to INDEX – dido

+0

W takim przypadku należy opublikować wynik polecenia "POKAŻ INDEKSY OD table_name". Uruchomiłem zapytanie w wierszu 3M w teście i wróciłem nieco ponad 1 na moim laptopie. Pomocne może być dodanie pełnej struktury tabeli (dane wyjściowe z 'POKAŻ UTWÓRZ tabelę nazwa_tabeli'). – nnichols

+0

Dodałem strukturę sql mojego stołu. – dido

1

Get MySQL EXPLAIN zapytaniu do ciebie. Wtedy zobaczysz, co indeksowanie poprawi.

1

EXPLAIN pokaże gdzie jest powolny i here're kilka pomysłów, jak w celu poprawy osiągów:

  • Dodaj indeksowania
  • klucze obce
  • Zastosowanie InnoDB
  • zapytanie podzielone na 2 i przetwarzaj je osobno w systemie lagnuage, którego używasz.
  • napisać ten sam pomysł w procedurze MySQL (nie jestem pewien, czy to byłoby szybkie).
1

Chciałbym użyć tabeli tymczasowej. 1.) wybierz wszystkie odpowiednie rekordy do tabeli temp, ustaw INDEX na id. 2.) zaktualizuj tabelę, używając czegoś podobnego do tego:

UPDATE table i, tmp_i 
SET i.flag = '1' 
WHERE i.id = tmp_i.id 
1

możesz spróbować (zakładając VB.net, ale można go zaimplementować w dowolnym języku).

Dim ids As String = Cmd.ExectueScalar("select group_concat(number) from (SELECT number FROM table GROUP BY number HAVING count(number) > 1)") 

Po otrzymać listę identyfikatorów (oddzielonych przecinkami) niż używać

UPDATE i 
SET i.flag = '1' 
WHERE i.number in (....) 

To może być powolne również, ale pierwszy - SELECT, nie będzie zamknąć bazę danych i replikację, etc .. UPDATE będzie szybszy.

Powiązane problemy