Ich habe ein ziemlich nerviges Problem. Ich möchte INNODB als meine Hauptdatenbank-Engine verwenden und auf MyISAM verzichten, da ich das erstere für die Verwendung von Galera-Cluster zur Redundanz benötige.
Ich habe die newbb_post
Tabelle in eine neue Tabelle kopiert (Beschreibung folgt) newbb_innopost
und in InnoDB geändert. Die Tabellen enthalten derzeit jeweils 5,390,146
Einträge.
Wenn Sie diese Auswahlen in einer neu gestarteten Datenbank ausführen (an dieser Stelle ist also kein Caching erforderlich!), Liefert die Datenbank die folgenden Ergebnisse (ohne die vollständige Ausgabe, bitte beachten Sie, dass ich die Datenbank nicht einmal auffordere, die Ergebnisse zu sortieren):
SELECT post.postid, post.attach FROM newbb_post AS post WHERE post.threadid = 51506; . . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 Zeilen im Satz (0,13 Sek.)
SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; . . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 Zeilen im Satz (1 Min. 22,19 Sek.)
0,13 Sekunden bis 86,19 Sekunden (!)
Ich frage mich, warum das passiert. Ich habe hier einige Antworten zu Stackexchange gelesen, die InnoDB betreffen, und einige schlagen vor, die innodb_buffer_pool
Größe auf 80% des installierten Arbeitsspeichers zu erhöhen . Dies wird das Problem nicht lösen, dass die anfängliche Abfrage einer bestimmten ID mindestens 50-mal länger dauert und den gesamten Web-Server zum Stillstand bringt, wodurch Verbindungen und Abfragen für die Datenbank in die Warteschlange gestellt werden. Anschließend wird der Cache / Puffer möglicherweise aktiviert, die Datenbank enthält jedoch mehr als 100.000 Threads. Daher ist es sehr wahrscheinlich, dass der Cache nie alle relevanten Abfragen enthält, die verarbeitet werden sollen.
Die obigen Abfragen sind einfach (keine Verknüpfungen) und alle Schlüssel werden verwendet:
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | id | select_type | tisch | Typ | Mögliche_Tasten | Schlüssel | key_len | ref | Reihen | Extra | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | 1 | EINFACH | post | ref | threadid, threadid_2, threadid_visible_dateline | threadid | 4 | const | 120144 | | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
Dies ist die MyISAM-Tabelle:
CREATE TABLE `newbb_post` ( `postid` int (10) ohne Vorzeichen NOT NULL AUTO_INCREMENT, `threadid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `parentid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `infraction` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `reportthreadid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `conversioned_2_utf8` int (11) NOT NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') NOT NULL DEFAULT 'on_nl2br', PRIMARY KEY (`postid`), KEY `threadid` (` threadid`, `userid`), KEY `importpost_index` (` importpostid`), KEY `dateline` (` dateline`), KEY `threadid_2` (` threadid`, `visible`,` dateline`), KEY `conversion_2_utf8` (` conversion_2_utf8`), KEY `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), KEY `ipaddress` (` ipaddress`), KEY `userid` (` userid`, `parentid`), KEY `user_date` (` userid`, `dateline`) ) ENGINE = MyISAM AUTO_INCREMENT = 5402802 DEFAULT CHARSET = latin1
und das ist die InnoDB-Tabelle (es ist genau das gleiche):
CREATE TABLE `newbb_innopost` ( `postid` int (10) ohne Vorzeichen NOT NULL AUTO_INCREMENT, `threadid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `parentid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) unsigned NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) NOT NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `infraction` smallint (5) ohne Vorzeichen NOT NULL DEFAULT '0', `reportthreadid` int (10) ohne Vorzeichen NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `conversioned_2_utf8` int (11) NOT NULL, `htmlstate` enum ('off', 'on', 'on_nl2br') NOT NULL DEFAULT 'on_nl2br', PRIMARY KEY (`postid`), KEY `threadid` (` threadid`, `userid`), KEY `importpost_index` (` importpostid`), KEY `dateline` (` dateline`), KEY `threadid_2` (` threadid`, `visible`,` dateline`), KEY `conversion_2_utf8` (` conversion_2_utf8`), KEY `threadid_visible_dateline` (` threadid`, `visible`,` dateline`, `userid`,` postid`), KEY `ipaddress` (` ipaddress`), KEY `userid` (` userid`, `parentid`), KEY `user_date` (` userid`, `dateline`) ) ENGINE = InnoDB AUTO_INCREMENT = 5402802 DEFAULT CHARSET = latin1
Server mit 32 GB RAM:
Serverversion: 10.0.12-MariaDB-1 ~ trusty-wsrep-log mariadb.org-Binärdistribution, wsrep_25.10.r4002
Wenn Sie alle Einstellungen für innodb_-Variablen benötigen, kann ich diese an diesen Beitrag anhängen.
Aktualisieren:
Ich habe ALLE Indizes außer dem Primärindex gelöscht, danach sah das Ergebnis so aus:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 Zeilen im Satz (29,74 Sek.)
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | id | select_type | tisch | Typ | Mögliche_Tasten | Schlüssel | key_len | ref | Reihen | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | 1 | EINFACH | post | ALL | NULL | NULL | NULL | NULL | 5909836 | Verwenden von where | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + 1 Reihe im Satz (0,00 Sek.)
Danach habe ich nur einen Index zurück zum Mix hinzugefügt, threadid, die Ergebnisse waren die folgenden:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 Zeilen im Satz (11,58 Sek.)
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | id | select_type | tisch | Typ | Mögliche_Tasten | Schlüssel | key_len | ref | Reihen | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | 1 | EINFACH | post | ref | threadid | threadid | 4 | const | 124622 | | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + 1 Reihe im Satz (0,00 Sek.)
Seltsamerweise dauerte der vollständige Scan ohne relevante Indizes nur 29 Sekunden, verglichen mit 88 Sekunden bei Verwendung von Indizes (!).
Mit nur einem perfekt zugeschnittenen Index dauert es immer noch 11 Sekunden, bis der Vorgang abgeschlossen ist - immer noch viel zu langsam für den tatsächlichen Gebrauch.
Update 2:
Ich habe MySQL (5.5.38-0ubuntu0.14.04.1 (Ubuntu)) auf einem anderen Server mit genau derselben Hardwarekonfiguration und genau derselben Datenbank / denselben Tabellen eingerichtet.
Die Ergebnisse sind nahezu identisch, zunächst die MyISAM-Tabelle:
. . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 Zeilen im Satz (0,14 Sek.)
Und das ist das Ergebnis der InnoDB-Tabelle
. . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 Zeilen im Satz (1 Min. 17,63 Sek.)
UPDATE 3: der Inhalt von my.cnf
# MariaDB-Datenbankserver-Konfigurationsdatei. # # Sie können diese Datei in eines der folgenden Verzeichnisse kopieren: # - "/etc/mysql/my.cnf", um globale Optionen festzulegen, # - "~ / .my.cnf", um benutzerspezifische Optionen festzulegen. # # Man kann alle langen Optionen verwenden, die das Programm unterstützt. # Führen Sie das Programm mit --help aus, um eine Liste der verfügbaren Optionen zu erhalten # --print-Defaults, um zu sehen, was es tatsächlich verstehen und verwenden würde. # # Erläuterungen siehe # http://dev.mysql.com/doc/mysql/de/server-system-variables.html # Dies wird an alle MySQL-Clients weitergegeben # Es wurde berichtet, dass Passwörter mit Häkchen / Anführungszeichen versehen werden sollten # besonders wenn sie "#" Zeichen enthalten ... # Denken Sie daran, /etc/mysql/debian.cnf zu bearbeiten, wenn Sie die Position des Sockets ändern. [Klient] port = 3306 socket = /var/run/mysqld/mysqld.sock # Hier finden Sie Einträge für bestimmte Programme # Die folgenden Werte setzen voraus, dass Sie mindestens 32M RAM haben # Dies war formal als [safe_mysqld] bekannt. Beide Versionen werden derzeit analysiert. [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nett = 0 [mysqld] # # * Grundeinstellungen # user = mysql pid-file = /var/run/mysqld/mysqld.pid socket = /var/run/mysqld/mysqld.sock port = 3306 basedir = / usr datadir = / var / lib / mysql tmpdir = / tmp lc_messages_dir = / usr / share / mysql lc_messages = de_DE überspringen-extern-verriegeln # # Anstatt zu überspringen, wird standardmäßig nur noch zugehört # localhost ist kompatibler und nicht weniger sicher. Bindeadresse = 127.0.0.1 # # * Feintuning # max_connections = 100 connect_timeout = 5 wait_timeout = 600 max_allowed_packet = 16M thread_cache_size = 128 sort_buffer_size = 4M bulk_insert_buffer_size = 16M tmp_table_size = 32M max_heap_table_size = 32M # # * MyISAM # # Dies ersetzt das Startskript und überprüft bei Bedarf MyISAM-Tabellen # das erste Mal, wenn sie berührt werden. Im Fehlerfall eine Kopie anfertigen und eine Reparatur versuchen. myisam_recover = BACKUP key_buffer_size = 128 MB # open-files-limit = 2000 table_open_cache = 400 myisam_sort_buffer_size = 512M concurrent_insert = 2 read_buffer_size = 2M read_rnd_buffer_size = 1M # # * Abfrage-Cache-Konfiguration # # Nur winzige Ergebnismengen zwischenspeichern, damit wir mehr in den Abfragecache passen. query_cache_limit = 128 KB query_cache_size = 64M # für schreibintensivere Setups auf DEMAND oder OFF setzen #query_cache_type = DEMAND # # * Protokollierung und Replikation # # Beide Standorte werden durch den Cronjob gedreht. # Beachten Sie, dass dieser Protokolltyp ein Leistungskiller ist. # Ab 5.1 können Sie das Log zur Laufzeit aktivieren! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # Die Fehlerprotokollierung wird aufgrund von /etc/mysql/conf.d/mysqld_safe_syslog.cnf an syslog gesendet. # # Wir möchten Informationen zu Netzwerkfehlern und dergleichen erhalten log_warnings = 2 # # Aktivieren Sie das Protokoll für langsame Abfragen, um Abfragen mit besonders langer Dauer anzuzeigen #slow_query_log [= {0 | 1}] slow_query_log_file = /var/log/mysql/mariadb-slow.log long_query_time = 10 #log_slow_rate_limit = 1000 log_slow_verbosity = query_plan # Protokollabfragen, die keine Indizes verwenden #log_slow_admin_statements # # Folgendes kann zur einfachen Wiedergabe von Sicherungsprotokollen oder zur Replikation verwendet werden. # Hinweis: Wenn Sie einen Replikations-Slave einrichten, lesen Sie README.Debian # andere Einstellungen, die Sie möglicherweise ändern müssen. # server-id = 1 #report_host = master1 #auto_increment_increment = 2 #auto_increment_offset = 1 log_bin = / var / log / mysql / mariadb-bin log_bin_index = /var/log/mysql/mariadb-bin.index # nicht fabelhaft für die Leistung, aber sicherer #sync_binlog = 1 expire_logs_days = 10 max_binlog_size = 100M # Sklaven #relay_log = / var / log / mysql / relay-bin #relay_log_index = /var/log/mysql/relay-bin.index #relay_log_info_file = /var/log/mysql/relay-bin.info #log_slave_updates #schreibgeschützt # # Wenn Anwendungen dies unterstützen, verhindert dieser strengere sql_mode einige # Fehler wie das Einfügen ungültiger Daten usw. #sql_mode = NO_ENGINE_SUBSTITUTION, TRADITIONAL # # * InnoDB # # InnoDB ist standardmäßig mit einer 10-MB-Datendatei in / var / lib / mysql / aktiviert. # Lesen Sie das Handbuch für weitere InnoDB-bezogene Optionen. Da sind viele! default_storage_engine = InnoDB # Sie können die Größe der Protokolldatei nicht einfach ändern, da hierfür spezielle Verfahren erforderlich sind #innodb_log_file_size = 50M innodb_buffer_pool_size = 20G innodb_log_buffer_size = 8M innodb_file_per_table = 1 innodb_open_files = 400 innodb_io_capacity = 400 innodb_flush_method = O_DIRECT # # * Sicherheitsfunktionen # # Lesen Sie auch das Handbuch, wenn Sie Chroot wollen! # chroot = / var / lib / mysql / # # Für die Erzeugung von SSL-Zertifikaten empfehle ich die OpenSSL-GUI "tinyca". # # ssl-ca = /etc/mysql/cacert.pem # ssl-cert = /etc/mysql/server-cert.pem # ssl-key = / etc / mysql / server-key.pem [mysqldump] schnell Anführungszeichen max_allowed_packet = 16M [MySQL] # no-auto-rehash # schnellerer Start von MySQL, aber keine Tab-Vervollständigung [isamchk] key_buffer = 16M # # * WICHTIG: Zusätzliche Einstellungen, die die Einstellungen aus dieser Datei überschreiben können! # Die Dateien müssen mit '.cnf' enden, sonst werden sie ignoriert. # ! includedir /etc/mysql/conf.d/
Und der Inhalt der inno-Variablen:
MariaDB [(none)]> SHOW VARIABLES LIKE 'inno%'; + ------------------------------------------- + ----- ------------------- + | Variablenname | Wert | + ------------------------------------------- + ----- ------------------- + | innodb_adaptive_flushing | ON | | innodb_adaptive_flushing_lwm | 10 | | innodb_adaptive_hash_index | ON | | innodb_adaptive_hash_index_partitions | 1 | | innodb_adaptive_max_sleep_delay | 150000 | | innodb_additional_mem_pool_size | 8388608 | | innodb_api_bk_commit_interval | 5 | | innodb_api_disable_rowlock | AUS | | innodb_api_enable_binlog | AUS | | innodb_api_enable_mdl | AUS | | innodb_api_trx_level | 0 | | innodb_autoextend_increment | 64 | | innodb_autoinc_lock_mode | 1 | | innodb_buffer_pool_dump_at_shutdown | AUS | | innodb_buffer_pool_dump_now | AUS | | innodb_buffer_pool_filename | ib_buffer_pool | | innodb_buffer_pool_instances | 8 | | innodb_buffer_pool_load_abort | AUS | | innodb_buffer_pool_load_at_startup | AUS | | innodb_buffer_pool_load_now | AUS | | innodb_buffer_pool_populate | AUS | | innodb_buffer_pool_size | 21474836480 | | innodb_change_buffer_max_size | 25 | | innodb_change_buffering | alle | | innodb_checksum_algorithm | innodb | | innodb_checksums | ON | | innodb_cleaner_lsn_age_factor | high_checkpoint | | innodb_cmp_per_index_enabled | AUS | | innodb_commit_concurrency | 0 | | innodb_compression_failure_threshold_pct | 5 | | innodb_compression_level | 6 | | innodb_compression_pad_pct_max | 50 | | innodb_concurrency_tickets | 5000 | | innodb_corrupt_table_action | behaupten | | innodb_data_file_path | ibdata1: 12M: autoextend | | innodb_data_home_dir | | | innodb_disable_sort_file_cache | AUS | | innodb_doublewrite | ON | | innodb_empty_free_list_algorithm | backoff | | innodb_fake_changes | AUS | | innodb_fast_shutdown | 1 | | innodb_file_format | Antilope | | innodb_file_format_check | ON | | innodb_file_format_max | Antilope | | innodb_file_per_table | ON | | innodb_flush_log_at_timeout | 1 | | innodb_flush_log_at_trx_commit | 1 | | innodb_flush_method | O_DIRECT | | innodb_flush_neighbors | 1 | | innodb_flushing_avg_loops | 30 | | innodb_force_load_corrupted | AUS | | innodb_force_recovery | 0 | | innodb_foreground_preflush | exponential_backoff | | innodb_ft_aux_table | | | innodb_ft_cache_size | 8000000 | | innodb_ft_enable_diag_print | AUS | | innodb_ft_enable_stopword | ON | | innodb_ft_max_token_size | 84 | | innodb_ft_min_token_size | 3 | | innodb_ft_num_word_optimize | 2000 | | innodb_ft_result_cache_limit | 2000000000 | | innodb_ft_server_stopword_table | | | innodb_ft_sort_pll_degree | 2 | | innodb_ft_total_cache_size | 640000000 | | innodb_ft_user_stopword_table | | | innodb_io_capacity | 400 | | innodb_io_capacity_max | 2000 | | innodb_kill_idle_transaction | 0 | | innodb_large_prefix | AUS | | innodb_lock_wait_timeout | 50 | | innodb_locking_fake_changes | ON | | innodb_locks_unsafe_for_binlog | AUS | | innodb_log_arch_dir | ./ | | innodb_log_arch_expire_sec | 0 | | innodb_log_archive | AUS | | innodb_log_block_size | 512 | | innodb_log_buffer_size | 8388608 | | innodb_log_checksum_algorithm | innodb | | innodb_log_compressed_pages | ON | | innodb_log_file_size | 50331648 | | innodb_log_files_in_group | 2 | | innodb_log_group_home_dir | ./ | | innodb_lru_scan_depth | 1024 | | innodb_max_bitmap_file_size | 104857600 | | innodb_max_changed_pages | 1000000 | | innodb_max_dirty_pages_pct | 75 | | innodb_max_dirty_pages_pct_lwm | 0 | | innodb_max_purge_lag | 0 | | innodb_max_purge_lag_delay | 0 | | innodb_mirrored_log_groups | 1 | | innodb_monitor_disable | | | innodb_monitor_enable | | | innodb_monitor_reset | | | innodb_monitor_reset_all | | | innodb_old_blocks_pct | 37 | | innodb_old_blocks_time | 1000 | | innodb_online_alter_log_max_size | 134217728 | | innodb_open_files | 400 | | innodb_optimize_fulltext_only | AUS | | innodb_page_size | 16384 | | innodb_print_all_deadlocks | AUS | | innodb_purge_batch_size | 300 | | innodb_purge_threads | 1 | | innodb_random_read_ahead | AUS | | innodb_read_ahead_threshold | 56 | | innodb_read_io_threads | 4 | | innodb_read_only | AUS | | innodb_replication_delay | 0 | | innodb_rollback_on_timeout | AUS | | innodb_rollback_segments | 128 | | innodb_sched_priority_cleaner | 19 | | innodb_show_locks_held | 10 | | innodb_show_verbose_locks | 0 | | innodb_sort_buffer_size | 1048576 | | innodb_spin_wait_delay | 6 | | innodb_stats_auto_recalc | ON | | innodb_stats_method | nulls_equal | | innodb_stats_on_metadata | AUS | | innodb_stats_persistent | ON | | innodb_stats_persistent_sample_pages | 20 | | innodb_stats_sample_pages | 8 | | innodb_stats_transient_sample_pages | 8 | | innodb_status_output | AUS | | innodb_status_output_locks | AUS | | innodb_strict_mode | AUS | | innodb_support_xa | ON | | innodb_sync_array_size | 1 | | innodb_sync_spin_loops | 30 | | innodb_table_locks | ON | | innodb_thread_concurrency | 0 | | innodb_thread_sleep_delay | 10000 | | innodb_track_changed_pages | AUS | | innodb_undo_directory | . | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 0 | | innodb_use_atomic_writes | AUS | | innodb_use_fallocate | AUS | | innodb_use_global_flush_log_at_trx_commit | ON | | innodb_use_native_aio | ON | | innodb_use_stacktrace | AUS | | innodb_use_sys_malloc | ON | | innodb_version | 5.6.17-65.0 | | innodb_write_io_threads | 4 | + ------------------------------------------- + ----- ------------------- + 143 Zeilen im Satz (0,02 Sek.)
Die Anzahl der Kerne der Maschine ist 8, es ist ein
Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
ab /proc/cpuinfo
Eine letzte Anmerkung: Die Abfragen wurden mit den von RolandoMYSQLDBA vorgeschlagenen Indizes ausgeführt, und die Abfragen dauerten jeweils ca. 11-20 Sekunden. Ich möchte darauf hinweisen, dass es für mich von entscheidender Bedeutung ist (dies ist die Haupttabelle eines Bulletin Boards), dass die erste Abfrage nach einer Thread-ID in weniger als einer Sekunde erfolgt, da ständig mehr als 60.000 Threads und Google-Bots gecrawlt werden diese Fäden.
quelle
Antworten:
IHRE ANFRAGE
Auf den ersten Blick sollte diese Abfrage nur 1,1597% (62510 von 5390146) der Tabelle berühren. Bei der Schlüsselverteilung von threadid 51506 sollte es schnell gehen.
REALITY-CHECK
Unabhängig davon, welche Version von MySQL (Oracle, Percona, MariaDB) Sie verwenden, kann keine von ihnen gegen einen gemeinsamen Gegner antreten: Die InnoDB-Architektur.
CLUSTERED INDEX
Bitte beachten Sie, dass an jeden Thread-ID-Eintrag ein Primärschlüssel angehängt ist. Dies bedeutet, dass beim Lesen aus dem Index eine Primärschlüsselsuche im ClusteredIndex (intern gen_clust_index) durchgeführt werden muss . Im ClusteredIndex enthält jede InnoDB-Seite sowohl Daten- als auch PRIMARY KEY-Indexinformationen. Weitere Informationen finden Sie in meinem Beitrag Best of MyISAM und InnoDB .
REDUNDANTE INDEXE
Sie haben viel Durcheinander in der Tabelle, da einige Indizes die gleichen führenden Spalten haben. MySQL und InnoDB müssen durch das Index-Durcheinander navigieren, um zu den benötigten BTREE-Knoten zu gelangen. Sie sollten dieses Durcheinander reduzieren, indem Sie Folgendes ausführen:
Warum diese Indizes entfernen?
threadid_2
undthreadid_visible_dateline
beginnen Sie mit den gleichen drei Spaltenthreadid_visible_dateline
postid wird nicht benötigt, da es sich um den PRIMARY KEY handelt und dieser eingebettet istPUFFER CACHING
Der InnoDB-Pufferpool speichert Daten und Indexseiten zwischen. MyISAM speichert nur Indexseiten.
Nur in diesem Bereich verschwendet MyISAM keine Zeit mit dem Zwischenspeichern von Daten. Das liegt daran, dass es nicht zum Zwischenspeichern von Daten entwickelt wurde. InnoDB speichert jede Daten- und Indexseite (und deren Großmutter) zwischen, die es berührt. Wenn Ihr InnoDB-Pufferpool zu klein ist, können Sie in einer Abfrage Seiten zwischenspeichern, Seiten ungültig machen und Seiten entfernen.
TISCHLAYOUT
Sie könnten etwas Platz aus der Reihe rasieren, indem Sie
importthreadid
und in Betracht ziehenimportpostid
. Sie haben sie als BIGINTs. Sie belegen im ClusteredIndex 16 Bytes pro Zeile.Sie sollten dies ausführen
Hiermit wird empfohlen, welche Datentypen diese Spalten für das angegebene Dataset haben sollten.
FAZIT
MyISAM hat viel weniger zu kämpfen als InnoDB, insbesondere im Bereich Caching.
Während Sie die Größe von RAM (
32GB
) und die Version von MySQL (Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002
) enthüllt haben, gibt es noch andere Teile dieses Puzzles, die Sie nicht enthüllt habenmy.cnf
Wenn Sie diese Dinge zur Frage hinzufügen können, kann ich sie weiter ausführen.
UPDATE 28.08.2014 11:27 Uhr EDT
Sie sollten Threading erhöhen
Ich würde in Betracht ziehen, den Abfragecache zu deaktivieren. (Siehe meinen letzten Beitrag Warum ist query_cache_type standardmäßig deaktiviert? Starten Sie mit MySQL 5.6. )
Ich würde den Pufferpool erhalten
Bereinigungs-Threads erhöhen (wenn Sie DML für mehrere Tabellen ausführen)
VERSUCHE ES !!!
quelle
@RolandMySQLDBA hat den richtigen Hinweis zur Beantwortung der Frage gegeben. Das Problem scheint in der Abfrage zu liegen, und damit die Ergebnisse zurückgegeben werden können, muss jedes dieser Felder gelesen werden (irgendwie aus der Datenbank).
Ich habe alle Indizes außer dem gelöscht
PRIMARY KEY
und diesen neuen Index eingefügt:ALTER TABLE newbb_innopost ADD INDEX threadid_visible_dateline_index (threadid,visible,dateline,userid,attach,ipaddress);
Dieser Link erklärt, was hier passiert ( abdeckender Index ): Die abgefragten Felder der Abfrage
postid,attach
können nun aus dem Schlüssel selbst extrahiert werden. Das erspart das Überprüfen der realen Daten und das Verwenden von E / A auf der Festplatte.Alle Abfragen laufen jetzt mit 0,00 Sekunden .. :)
Vielen Dank für Ihre Hilfe.
Edit : Das eigentliche Grundproblem ist nicht gelöst, ich habe es nur mit dieser Technik umgangen. InnoDB muss in diesem Bereich dringend repariert werden.
quelle
SQL_NO_CACHE
.Basierend auf Ihrer Abfrage und Tabelle scheinen Sie Daten aus einer Zeitreihentabelle auszuwählen. Als solches kann es sein, dass die Abfragezeit langsam ist, weil Sie gleichzeitig einfügen?
Wenn diese beiden Dinge zutreffen, kann ich dann vorschlagen, sich alternativ mit ScaleDB zu befassen? Sie werden immer noch auf MariaDB sein, nur (vielleicht) eine passendere Engine.
http://www.scaledb.com - Homepage http://www.scaledb.com/download-form.php - unser Produkt
quelle
Mit beiden Engines wird die Abfrage viel schneller ausgeführt
Dies liegt daran, dass es sich um einen "abdeckenden" Index handelt, der praktisch auf die gleiche Weise funktioniert (unter Verwendung des Index BTree).
Außerdem werde ich sagen, dass dies für beide Engines auf einem "kalten" Server nicht möglich ist :
Bitte verwenden Sie diese
SQL_NO_CACHE
Option, wenn Timings ausgeführt werden. Wir möchten nicht, dass der Abfrage-Cache die Schlussfolgerungen verfälscht.Ein weiterer schneller Ansatz (unabhängig vom I / O-Caching):
Verwenden Sie InnoDB und wechseln Sie von
PRIMARY KEY (postid)
zuDer Grund dafür ist , dass diese alle relevanten Reihen verursachen benachbart sein, um dadurch die weniger I / O, etc. Das
INDEX(postid)
ist zu haltenAUTO_INCREMENT
glücklich. Vorsichtsmaßnahme: Dies führt zu Problemen mit allen Sekundärschlüsseln - einige sind schneller, andere langsamer.quelle
Obwohl dies nicht direkt auf @jollyroger zutrifft, da er bereits die richtige Einstellung hat, wurde die Änderung
innodb_buffer_pool_size
des RAM- Werts auf 70% erheblich verbessert, wie in Warum ist myisam langsamer als Innodb erläutertZunächst
MyISAM
war langsam, aber oke. DannInnoDB
machten die Dinge schlimm, ähnlich wie die 100x langsamer in dieser Frage und nach dem Ändern der Einstellung wurdeInnoDB
dann 10x schnellerMyISAM
.Meine Standardeinstellung war 8 MB, was viel zu wenig ist.
quelle