5

W moim wolnym dziennika zapytań widzę powolnych zapytań jakMySQL powolne kwerendy, która używa indeksu, a nie zwalniać, gdy uruchomię go przez profilera

 
# Time: 121107 16:34:02 
# [email protected]: web_node[web_node] @ localhost [127.0.0.1] 
# Thread_id: 34436186 Schema: test_db Last_errno: 0 Killed: 0 
# Query_time: 1.413751 Lock_time: 0.000222 Rows_sent: 203 Rows_examined: 203 Rows_affected: 0 Rows_read: 203 
# Bytes_sent: 7553 Tmp_tables: 0 Tmp_disk_tables: 0 Tmp_table_sizes: 0 
# InnoDB_trx_id: 9B04384 
SET timestamp=1352334842; 
SELECT id, email FROM test_data WHERE id IN (13089576,3002681,3117763,1622233,2941590,12305279,1732672,2446772,3189510,13084725,4943929,5855071,6572137,2266261,3003496,2024860,3336832,13758671,6477694,1796684,13001771,4690025,1071744,1017876,5175795,795988,1619821,2481819,2941090,4770802,13438250,3254708,2323402,526303,13219855,3313573,3190479,1733761,3300577,2941758,6474118,1733379,11523598,4205064,6521805,2492903,1860388,3337093,5205317,1213970,5442738,12194039,1214203,12970536,3076611,3126152,3677156,5305021,2751587,4954875,875480,2105172,5309382,12981920,5204330,13729768,3254503,5030441,2680750,590661,1338572,7272410,1860386,2567550,5434143,1918035,5329411,1683235,3254119,5175784,1855380,3336834,2102567,4749746,37269,3207031,6464336,2227907,2713471,3937600,2940442,2233821,5619141,5204711,5988803,5050821,10109926,5226877,5050275,1874115,13677832,5338699,2423773,6432937,6443660,1990611,6090667,6527411,6568731,3254846,3414049,2011907,5180984,12178711,8558260,3130655,5864745,2059318,3480233,2104948,2387703,1939395,5356002,2681209,1184622,1184456,10390165,510854,7983305,795991,2622393,4490187,9436477,5356051,2423464,5205318,1600499,13623229,3255205,12200483,6477706,3445661,5226284,1176639,13760962,2101681,6022818,12909371,1732457,2377496,7260091,12191702,2492899,2630691,13047691,1684470,9382108,2233737,13117701,1796698,2535914,4941741,4565958,1100410,2321180,13080467,813342,4563877,4689365,2104756,1102802,2714488,3188947,1599770,1558291,5592740,5233428,5204830,1574452,3188956,13693326,2102349,3704111,1748303,790889,9323280,4741494,2387900,5338213,3583795,2283942,3189482,3002296,4490123,3585020,962926,3481423,1600920,1682364,4693123,6487778,2677582,2377195);

Kiedy uruchomić powolny zapytanie przez profilera korzystania SQL_NO_CACHE wygląda mówi

 
203 rows in set (0.03 sec) 

show profile for query 33; 
+----------------------+----------+ 
| Status    | Duration | 
+----------------------+----------+ 
| starting    | 0.000187 | 
| checking permissions | 0.000012 | 
| Opening tables  | 0.000034 | 
| System lock   | 0.000016 | 
| init     | 0.000087 | 
| optimizing   | 0.000024 | 
| statistics   | 0.028694 | 
| preparing   | 0.000074 | 
| executing   | 0.000005 | 
| Sending data   | 0.001596 | 
| end     | 0.000009 | 
| query end   | 0.000008 | 
| closing tables  | 0.000014 | 
| freeing items  | 0.001600 | 
| logging slow query | 0.000007 | 
| cleaning up   | 0.000011 | 
+----------------------+----------+ 

kiedy uruchomić zapytanie o wyjaśnienie mówi

 
+----+-------------+------------------+-------+------------------+----------+---------+------+------+--------------------------+ 
| id | select_type | table   | type | possible_keys | key  | key_len | ref | rows | Extra     | 
+----+-------------+------------------+-------+------------------+----------+---------+------+------+--------------------------+ 
| 1 | SIMPLE  | test_data  | range | PRIMARY,id_email | id_email | 4  | NULL | 203 | Using where; Using index | 
+----+-------------+------------------+-------+------------------+----------+---------+------+------+--------------------------+ 

tabeli przeglądowej tworzyć s jak

 
CREATE TABLE `test_data` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `email` varchar(254) DEFAULT NULL, 
    `domain` varchar(254) DEFAULT NULL, 
    `age` smallint(6) DEFAULT NULL, 
    `gender` tinyint(1) DEFAULT NULL, 
    `location_id` int(11) unsigned DEFAULT NULL, 
    `created` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `unistall_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `subscription_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `active` tinyint(1) DEFAULT '1', 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `email` (`email`), 
    KEY `domain` (`domain`), 
    KEY `id_email` (`id`,`email`), 
    KEY `email_id` (`email`,`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=13848530 DEFAULT CHARSET=utf8 

Jest inna kwerendy, która pobiera kursują regularnie wybierając identyfikator i e-mail z listy adresów e-mail stąd email, klucz ID, adres e-mail muszą być unikalne stąd dlatego, że jest unikalnym kluczem. Stół ma tylko ~ 14 mln wierszy.

Pomyślałem, że może indeksy, w których do dużych na pamięć i zamiana, ale pudełko ma 8 gigów ram.

 
SELECT table_schema "Data Base Name", SUM(data_length + index_length)/1024/1024 "Data Base Size in MB", SUM(index_length)/1024/1024 "Index Size in MB" FROM information_schema.TABLES GROUP BY table_schema; 
+--------------------+----------------------+------------------+ 
| Data Base Name  | Data Base Size in MB | Index Size in MB | 
+--------------------+----------------------+------------------+ 
| metrics   |  3192.50000000 | 1594.42187500 | 
| data    |  8096.48437500 | 5639.51562500 | 
| raw_data   |  6000.35937500 |  745.07812500 | 
| information_schema |   0.00878906 |  0.00878906 | 
| mysql    |   0.04319191 |  0.04101563 | 
| performance_schema |   0.00000000 |  0.00000000 | 
+--------------------+----------------------+------------------+ 

Ustawianie innodb_file_per_table = 1 w pliku my.cnf wydaje się rozwiązać ten problem.

Poprawiłam czas wykonania, rozumiem, że posiadanie pojedynczego pliku na stole oznacza, że ​​igła dysku nie musi poruszać się na tak dużych odległościach.

Pytania

  1. Jeśli zapytanie może być oceniany za pomocą indeksów dlaczego ustawienie innodb_file_per_table = 1 poprawić wydajność
  2. Dlaczego existing kwerenda powolne, gdy jest on prowadzony przez profilera bez korzystania z pamięci podręcznej ?
  3. Czy mój klucz podstawowy powinien być (identyfikator, e-mail)?

Aktualizacja

Początkowo nie było pliku /etc/my.cnf potem stworzył jedną z następującym

 
[mysqld] 
server-id=1 
max_connections=1500 
key_buffer_size=50M 
query_cache_limit=16M 
query_cache_size=256M 
thread_cache=16 
table_open_cache=4096 
sort_buffer_size=512K 
join_buffer_size=8M 
read_buffer_size=8M 
skip_name_resolve=1 
thread_cache_size=256 
innodb_buffer_pool_size=6G 
innodb_buffer_pool_instances=1 
innodb_thread_concurrency=96 
innodb_additional_mem_pool_size=32M 
innodb_log_buffer_size=8M 
innodb_flush_log_at_trx_commit=0 
innodb_log_file_size=256M 
innodb_flush_method=O_DIRECT 
innodb_file_per_table=1 
net_read_timeout=15 
net_write_timeout=30 
log-bin=mysql-bin 
sync_binlog=0 
datadir=/var/lib/mysql 

Odpowiedz

3

Masz zbyt wiele danych do innodb_log_buffer.

Jakie są wartości:

innodb_buffer_pool_size 
innodb_log_file_size 

Cała InnoDB musi prowadzone w pamięci. Po podzieleniu plików działa on bardziej wydajnie, ponieważ jest wymieniany i usuwany z pamięci przy mniejszej ilości odczytów i zapisów na dysku, ponieważ jeden większy plik wymaga więcej czasu na skanowanie danych.

Nie zamienia się, ponieważ twoje innodb_buffer_pool_size ogranicza ilość pamięci ładowanej przez MySQL do pamięci.

Jedynym sposobem na rozwiązanie problemu jest uzyskanie większej ilości pamięci i przydzielenie wystarczającej ilości innodb_buffer_pool_size dla wszystkich tabel i indeksów innodb.

+0

dzięki za wyjaśnienie, zaktualizowałem oryginalne pytanie z odpowiedzią na twoje pytanie. – Ben

+1

Tak - innodb_buffer_pool_size = 6G - Twoje dane nie będą się w tym mieściły. Masz 16,8 GB danych i indeks. Jeśli możesz zwiększyć pamięć, to jest twój najlepszy zakład, w przeciwnym razie rozważałbym przeniesienie niektórych danych do tablicy ARCHIWUM. – Michael