2016-01-26 9 views
10

Mam zapytanie, które działa w ciągu około 20 sekund na serwerze MySQL 5.1, ale trwa prawie 15 minut na serwerze MariaDB 5.5. Zwykłe podejrzane, takie jak key_buffer_size i tmp_table_size i max_heap_table_size, są równe (128M). Większość ustawień jest równy miarę widzę (query_cache itp)Mariadb 5.5 wolniejszy niż MySQL 5.1

Zapytanie:

SELECT products.id, 
concat(publications.company_name,' [',publications.quote,'] ', products.name) as n, 
products.impressions, 
products.contacts, 
is_channel, 
sl.i, 
count(*) 
FROM products 
LEFT JOIN publications ON products.publications_id = publications.id 
LEFT OUTER JOIN ( 
    SELECT adspace.id AS i, 
    slots.products_id FROM adspace 
    LEFT JOIN slots ON adspace.slots_id = slots.id 
     AND adspace.end > '2016-01-25 10:28:49' 
     WHERE adspace.active = 1) AS sl 
    ON sl.products_id = products.id 
WHERE 1 = 1 
AND publications.active=1 
GROUP BY products.id 
ORDER BY n ASC; 

Jedyna różnica jest w fase wyjaśnić:

stary serwer (MySQL 5.1)

+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref          | rows | Extra       | 
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 
| 1 | PRIMARY  | products  | ALL | NULL   | NULL | NULL | NULL         | 6568 | Using temporary; Using filesort | 
| 1 | PRIMARY  | publications | eq_ref | PRIMARY  | PRIMARY | 4  | db.products.publications_id |  1 | Using where         | 
| 1 | PRIMARY  | <derived2> | ALL | NULL   | NULL | NULL | NULL         | 94478 |         | 
| 2 | DERIVED  | adspace  | ALL | NULL   | NULL | NULL | NULL         | 101454 | Using where      | 
| 2 | DERIVED  | slots  | eq_ref | PRIMARY  | PRIMARY | 4  | db.adspace.slots_id   |  1 |            | 
+----+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 

Nowy serwer (MariaDB 5,5)

+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref          | rows | Extra       | 
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 
| 1 | SIMPLE  | products  | ALL | test_idx  | NULL | NULL | NULL         | 6557 | Using temporary; Using filesort | 
| 1 | SIMPLE  | publications | eq_ref | PRIMARY  | PRIMARY | 4  | db.products.publications_id |  1 | Using where         | 
| 1 | SIMPLE  | adspace  | ALL | NULL   | NULL | NULL | NULL         | 100938 | Using where      | 
| 1 | SIMPLE  | slots  | eq_ref | PRIMARY  | PRIMARY | 4  | db.adspace.slots_id   |  1 | Using where         | 
+------+-------------+--------------+--------+---------------+---------+---------+-----------------------------------------+--------+---------------------------------+ 

Indeks został dodany do tabeli produktów na nowym serwerze, aby przyspieszyć działanie, bezskutecznie.

zmienne Silnik:

starego serwera:

mysql> show variables like '%engine%'; 
+---------------------------+--------+ 
| Variable_name    | Value | 
+---------------------------+--------+ 
| engine_condition_pushdown | ON  | 
| storage_engine   | MyISAM | 
+---------------------------+--------+ 

mysql> show variables like '%buffer_pool%'; 
+-------------------------+---------+ 
| Variable_name   | Value | 
+-------------------------+---------+ 
| innodb_buffer_pool_size | 8388608 | 
+-------------------------+---------+ 

nowy serwer:

MariaDB [db]> show variables like '%engine%'; 
+---------------------------+--------+ 
| Variable_name    | Value | 
+---------------------------+--------+ 
| default_storage_engine | InnoDB | 
| engine_condition_pushdown | OFF | 
| storage_engine   | InnoDB | 
+---------------------------+--------+ 


MariaDB [db]> show variables like '%buffer_pool%'; 
+---------------------------------------+-----------+ 
| Variable_name       | Value  | 
+---------------------------------------+-----------+ 
| innodb_blocking_buffer_pool_restore | OFF  | 
| innodb_buffer_pool_instances   | 1   | 
| innodb_buffer_pool_populate   | OFF  | 
| innodb_buffer_pool_restore_at_startup | 0   | 
| innodb_buffer_pool_shm_checksum  | ON  | 
| innodb_buffer_pool_shm_key   | 0   | 
| innodb_buffer_pool_size    | 134217728 | 
+---------------------------------------+-----------+ 

Wszystkie tabele użyte w zapytaniu są MyISAM (zarówno starego i nowego serwera)

Profilowanie pokazało, że stare zapytanie zajmuje około 16 sekund w "kopiowaniu do tabeli tmp" i nowym s Erver około 800 sekund w tym fase.

Nowy serwer ma dyski SSD do przechowywania, a stare serwery mają zwykłe dyski.

Edytuj: Mam również serwer MySQL 5.5 i tam zapytanie zajmuje tylko około 10 sekund. Również z tymi samymi ustawieniami, o ile widzę.

Starałem się streścić je w tabeli:

Location:  Customer     Own      Customer 
MySQL Type:  MySQL      MySQL     MariaDB 
Mysql Version: 5.1.56-community-log  5.5.39-1-log (Debian) 5.5.44-MariaDB-log 
HDD:   Normal      Normal     SSD 
Type:   Virtual      Real     Virtual 
Query time:  ~15s      ~10s     ~15min 
DB engine:  MyISAM      InnoDB     InnoDB 
Table Engine: MyISAM      MyISAM     MyISAM 

nie chcą przepisać zapytanie (choć może korzystać z niektórych prac), ale chcę zobaczyć różnicę między 2 maszynach, mój Domyślam się, że ustawienie nie jest idealne w MariaDB, ale nie mogę go znaleźć.

+0

Czy na pewno używasz tego samego silnika tabeli dla obu baz danych? – Mjh

+0

Być może to odpowiada na twoje pytanie: Całkowicie inny silnik pamięci masowej ... – hendrik

+0

Więc jeśli rozumiem, że masz rację, silnik na poziomie bazy danych zrobi różnicę, nawet jeśli silnik na stole jest taki sam? – darkownage

Odpowiedz

4

Z powyższego wyjaśnienia widać, że użyto Derived Table Merge Optimization. To niestety w twoim przypadku oznacza, że ​​zamiast jednego pełnego skanowania tabeli ponad adspace wykonuje się około ~ 6k. Możliwe jest wyłączenie optymalizacji przed zapytaniem przez wydanie set optimizer_switch='derived_merge=off';.Kompatybilny wstecz będzie alternatywnie dodawanie GROUP BY adspace.id, slots.products_id do podzapytania (jeśli nie zmienia wyników - najbezpieczniejszy jest grupowanie przez PKs wszystkich połączonych tabel), który zabrania łączenia za pomocą innej semantyki.

Jest jeden zgłoszony o tym optimizer bug - Twój przypadek może w tym pomóc.

+0

Ustawienie deriv_merge = OFF spowodowało, że zapytanie zmieniło się z ~ 15min na ~ 0.3seconds. Mały wzrost prędkości :) – darkownage

+0

@darkownage - jestem zdezorientowany twoim komentarzem - czy było to znaczące _ spowolnienie? lub _zwiększyć_? –

+0

@RickJames - Przepraszamy za dziwne zdanie :) Zapytanie poszło od około 15 min do 0,5 sekundy. Wzrost prędkości był więc ogromny. Zdecydowaliśmy się wyłączyć tę "optymalizację", ponieważ była ona blokowana, a zapytanie wykonało zadanie i było najłatwiejsze. Mam nadzieję, że to odpowie na twoje pytanie :) – darkownage

1

To może nie być odpowiedź, ale MariaDB 5.5 używa innego algorytmu do wykonania sprzężenia. O ile wiem w MariaDB 5.5 wprowadzono Batch Key Access Join. Starsze wersje MySQL lub MariaDB używają innego. Mimo że nowa wersja powinna być w większości przypadków szybsza, być może Twoje konkretne tabele osiągają lepsze wyniki przy użyciu starej.

Edytuj: Ta odpowiedź może być przestarzała, ponieważ wspomniałeś, że używasz różnych silników do przechowywania.

Powiązane problemy