J'ai un problème assez ennuyant. Je souhaite utiliser INNODB comme moteur de base de données principal et abandonner MyISAM, car j’ai besoin du premier pour utiliser galera-cluster à des fins de redondance.
J'ai copié (la description suit) la newbb_post
table dans une nouvelle table appelée newbb_innopost
et l' ai modifiée en InnoDB. Les tables contiennent actuellement des 5,390,146
entrées chacune.
L'exécution de ces sélections sur une base de données fraîchement démarrée (afin qu'aucune mise en cache ne soit impliquée à ce stade!), La base de données donne les résultats suivants (en omettant la sortie complète, veuillez noter que je ne demande même pas à la base de données de trier les résultats):
SELECT post.postid, post.attach FROM newbb_post AS post WHERE post.threadid = 51506; . . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 lignes dans un ensemble (0.13 sec)
SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; . . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 lignes par séries (1 min 22.19 sec)
0,13 seconde à 86,19 secondes (!)
Je me demande pourquoi cela se produit. J'ai lu quelques réponses ici sur Stackexchange impliquant InnoDB et certaines suggèrent d'augmenter la innodb_buffer_pool
taille à 80% de la RAM installée. Cela ne résoudra pas le problème suivant: la requête initiale à un ID particulier prendra au moins 50 fois plus longtemps et bloquera la totalité de la recherche Web, mettant en file d'attente les connexions et les requêtes pour la base de données. Ensuite, le cache / tampon peut démarrer, mais il y a plus de 100 000 threads dans cette base de données. Il est donc très probable que le cache ne contiendra jamais toutes les requêtes pertinentes à traiter.
Les requêtes ci-dessus sont simples (pas de jointures) et toutes les clés sont utilisées:
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | id | select_type | table | type | possible_keys | clé | key_len | ref | rangées | Extra | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- + | 1 | SIMPLE | post | ref | threadid, threadid_2, threadid_visible_dateline | threadid | 4 | const | 120144 | | + ------ + ------------- + ------- + ------ + ------------- ---------------------------------- + ---------- + ---- ----- + ------- + -------- + ------- +
C'est la table MyISAM:
CREATE TABLE `newbb_post` ( `postid` int (10) non signé NOT NULL AUTO_INCREMENT, `threadid` int (10) non signé NOT NULL DEFAULT '0', `parentid` int (10) non signé NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) non signé NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) non signé NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) PAS NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) non signé NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) non signé NOT NULL DEFAULT '0', `infraction` smallint (5) non signé NOT NULL DEFAULT '0', `reportthreadid` int (10) non signé NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `convert_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`), CLÉ `converti_2_utf8` (` converti2_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 CHARGEMENT PAR DEFAUT = latin1
et voici la table InnoDB (c'est exactement la même chose):
CREATE TABLE `newbb_innopost` ( `postid` int (10) non signé NOT NULL AUTO_INCREMENT, `threadid` int (10) non signé NOT NULL DEFAULT '0', `parentid` int (10) non signé NOT NULL DEFAULT '0', `username` varchar (100) NOT NULL DEFAULT '', `userid` int (10) non signé NOT NULL DEFAULT '0', `title` varchar (250) NOT NULL DEFAULT '', `dateline` int (10) non signé NOT NULL DEFAULT '0', `pagetext` mediumtext, `allowmilie` smallint (6) PAS NULL DEFAULT '0', `showsignature` smallint (6) NOT NULL DEFAULT '0', `ipaddress` varchar (15) NOT NULL DEFAULT '', `iconid` smallint (5) non signé NOT NULL DEFAULT '0', `visible` smallint (6) NOT NULL DEFAULT '0', `attach` smallint (5) non signé NOT NULL DEFAULT '0', `infraction` smallint (5) non signé NOT NULL DEFAULT '0', `reportthreadid` int (10) non signé NOT NULL DEFAULT '0', `importthreadid` bigint (20) NOT NULL DEFAULT '0', `importpostid` bigint (20) NOT NULL DEFAULT '0', `convert_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`), CLÉ `converti_2_utf8` (` converti2_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 CHARGEMENT PAR DEFAUT = latin1
Serveur, avec 32 Go de RAM:
Version du serveur: 10.0.12-MariaDB-1 ~ trusty-wsrep-log distribution binaire de mariadb.org, wsrep_25.10.r4002
Si vous avez besoin de tous les paramètres innodb_ variables, je peux l’attacher à cet article.
Mise à jour:
J'ai abandonné TOUS les index en dehors de l'index primaire. Après, le résultat ressemblait à ceci:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 lignes dans la série (29.74 sec)
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | id | select_type | table | type | possible_keys | clé | key_len | ref | rangées | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + | 1 | SIMPLE | post | TOUS | NULL | NULL | NULL | NULL | 5909836 | Utiliser où | + ------ + ------------- + ------- + ------ + ------------- - + ------ + --------- + ------ + --------- + ------------- + 1 ligne dans le set (0.00 sec)
Après cela, je viens d'ajouter un index au mélange, threadid, les résultats sont les suivants:
. . | 5402697 | 0 | | 5402759 | 0 | + --------- + -------- + 62510 lignes dans le jeu (11.58 sec)
EXPLAIN SELECT post.postid, post.attach FROM newbb_innopost AS post WHERE post.threadid = 51506; + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | id | select_type | table | type | possible_keys | clé | key_len | ref | rangées | Extra | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + | 1 | SIMPLE | post | ref | threadid | threadid | 4 | const | 124622 | | + ------ + ------------- + ------- + ------ + ------------- - + ---------- + --------- + ------- + -------- + ------- + 1 ligne dans le set (0.00 sec)
Il est étrange que, sans index pertinents, l’analyse complète ne prenne que 29 secondes, contre 88 secondes avec les index (!).
Avec un seul index parfaitement adapté, il faut encore 11 secondes - encore beaucoup trop lentement pour une utilisation dans le monde réel.
Mise à jour 2:
J'ai installé MySQL (5.5.38-0ubuntu0.14.04.1 (Ubuntu)) sur un autre serveur avec exactement la même configuration matérielle et exactement la même base de données / tables.
Les résultats sont presque les mêmes, d’abord le tableau MyISAM:
. . | 5401593 | 0 | | 5401634 | 0 | + --------- + -------- + 62510 lignes dans un ensemble (0,14 sec)
Et ceci est le résultat de la table InnoDB
. . | 5397410 | 0 | | 5397883 | 0 | + --------- + -------- + 62510 lignes par série (1 min 17.63 sec)
UPDATE 3: le contenu de my.cnf
# Fichier de configuration du serveur de base de données MariaDB. # # Vous pouvez copier ce fichier dans l’un des fichiers suivants: # - "/etc/mysql/my.cnf" pour définir les options globales, # - "~ / .my.cnf" pour définir les options spécifiques à l'utilisateur. # # On peut utiliser toutes les options longues prises en charge par le programme. # Exécutez le programme avec --help pour obtenir une liste des options disponibles et avec # --print-defaults pour voir ce qu'il comprend et utilise réellement. # # Pour des explications voir # http://dev.mysql.com/doc/mysql/en/server-system-variables.html # Ceci sera transmis à tous les clients mysql # Il a été rapporté que les mots de passe devraient être entourés de ticks / guillemets # surtout si elles contiennent "#" des caractères ... # N'oubliez pas de modifier /etc/mysql/debian.cnf lors de la modification de l'emplacement du socket. [client] port = 3306 socket = /var/run/mysqld/mysqld.sock # Voici les entrées pour certains programmes spécifiques # Les valeurs suivantes supposent que vous avez au moins 32 millions de RAM # Ceci était officiellement connu sous le nom [safe_mysqld]. Les deux versions sont actuellement analysées. [mysqld_safe] socket = /var/run/mysqld/mysqld.sock nice = 0 [mysqld] # # * Paramètres de base # utilisateur = 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 = en_US sauter-verrouillage externe # # Au lieu de sauter le réseau, la valeur par défaut est maintenant d'écouter uniquement # localhost qui est plus compatible et n'est pas moins sécurisé. bind-address = 127.0.0.1 # # * Réglage fin # 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 # # Ceci remplace le script de démarrage et vérifie les tables MyISAM si nécessaire # la première fois qu'ils sont touchés. En cas d'erreur, faites une copie et essayez une réparation. myisam_recover = SAUVEGARDE key_buffer_size = 128M # 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 # # * Configuration du cache de requêtes # # Cache seulement les jeux de résultats minuscules, ainsi nous pouvons en insérer davantage dans le cache de requêtes. query_cache_limit = 128K query_cache_size = 64M # pour des configurations plus intensives en écriture, réglez sur DEMAND ou OFF #query_cache_type = DEMAND # # * Journalisation et réplication # # Les deux emplacements sont tournés par le cronjob. # Sachez que ce type de journal est un facteur de perte de performances. # À partir de la version 5.1, vous pouvez activer le journal au moment de l’exécution! #general_log_file = /var/log/mysql/mysql.log #general_log = 1 # # La journalisation des erreurs va à syslog en raison de /etc/mysql/conf.d/mysqld_safe_syslog.cnf. # # nous voulons connaître les erreurs de réseau et autres log_warnings = 2 # # Activer le journal de requête lent pour voir les requêtes avec une durée particulièrement longue #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 # log-queries-not-using-indexes #log_slow_admin_statements # # Les éléments suivants peuvent être utilisés pour relire facilement les journaux de sauvegarde ou pour la réplication. # remarque: si vous configurez un esclave de réplication, voir README.Debian à propos de # autres paramètres que vous devrez peut-être modifier. # id-serveur = 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 # pas fabuleux pour la performance, mais plus sûr #sync_binlog = 1 expire_logs_days = 10 max_binlog_size = 100M # des esclaves #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 #lecture seulement # # Si les applications le supportent, ce sql_mode plus strict empêche certaines # erreurs comme l'insertion de dates invalides, etc. #sql_mode = NO_ENGINE_SUBSTITUTION, TRADITIONAL # # * InnoDB # # InnoDB est activé par défaut avec un fichier de données de 10 Mo dans / var / lib / mysql /. # Lisez le manuel pour plus d'options liées à InnoDB. Il y a beaucoup de! default_storage_engine = InnoDB # vous ne pouvez pas simplement changer la taille du fichier journal, nécessite une procédure spéciale #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 # # * Fonctions de sécurité # # Lisez aussi le manuel, si vous voulez chroot! # chroot = / var / lib / mysql / # # Pour générer des certificats SSL, je recommande l'interface graphique OpenSSL "tinyca". # # ssl-ca = / etc / mysql / cacert.pem # ssl-cert = / etc / mysql / server-cert.pem # ssl-key = / etc / mysql / server-key.pem [mysqldump] rapide noms de citation max_allowed_packet = 16M [mysql] # no-auto-rehash # démarrage plus rapide de mysql mais pas de complétion des onglets [isamchk] key_buffer = 16M # # * IMPORTANT: paramètres supplémentaires pouvant remplacer ceux de ce fichier! # Les fichiers doivent se terminer par '.cnf', sinon ils seront ignorés. # ! includedir /etc/mysql/conf.d/
Et le contenu des variables inno:
MariaDB [(none)]> AFFICHER LES VARIABLES LIKE 'inno%'; + ------------------------------------------- + ----- ------------------- + | Nom_variable | La valeur | + ------------------------------------------- + ----- ------------------- + | 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 | OFF | | innodb_api_enable_binlog | OFF | | innodb_api_enable_mdl | OFF | | innodb_api_trx_level | 0 | | innodb_autoextend_increment | 64 | | innodb_autoinc_lock_mode | 1 | | innodb_buffer_pool_dump_at_shutdown | OFF | | innodb_buffer_pool_dump_now | OFF | | innodb_buffer_pool_filename | ib_buffer_pool | | innodb_buffer_pool_instances | 8 | | innodb_buffer_pool_load_abort | OFF | | innodb_buffer_pool_load_at_startup | OFF | | innodb_buffer_pool_load_now | OFF | | innodb_buffer_pool_populate | OFF | | innodb_buffer_pool_size | 21474836480 | | innodb_change_buffer_max_size | 25 | | innodb_change_buffering | tous | | innodb_checksum_algorithm | innodb | | innodb_checksums | ON | | innodb_cleaner_lsn_age_factor | high_checkpoint | | innodb_cmp_per_index_enabled | OFF | | 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 | affirmer | | innodb_data_file_path | ibdata1: 12M: autoextend | | innodb_data_home_dir | | | innodb_disable_sort_file_cache | OFF | | innodb_doublewrite | ON | | innodb_empty_free_list_algorithm | backoff | | innodb_fake_changes | OFF | | 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_nevisa | 1 | | innodb_flushing_avg_loops | 30 | | innodb_force_load_corrupted | OFF | | innodb_force_recovery | 0 | | innodb_foreground_preflush | exponential_backoff | | innodb_ft_aux_table | | | innodb_ft_cache_size | 8000000 | | innodb_ft_enable_diag_print | OFF | | 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 | OFF | | innodb_lock_wait_timeout | 50 | | innodb_locking_fake_changes | ON | | innodb_locks_unsafe_for_binlog | OFF | | innodb_log_arch_dir | ./ | | innodb_log_arch_expire_sec | 0 | | innodb_log_archive | OFF | | 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 | OFF | | innodb_page_size | 16384 | | innodb_print_all_deadlocks | OFF | | innodb_purge_batch_size | 300 | | innodb_purge_threads | 1 | | innodb_random_read_ahead | OFF | | innodb_read_ahead_threshold | 56 | | innodb_read_io_threads | 4 | | innodb_read_only | OFF | | innodb_replication_delay | 0 | | innodb_rollback_on_timeout | OFF | | 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 | OFF | | innodb_stats_persistent | ON | | innodb_stats_persistent_sample_pages | 20 | | innodb_stats_sample_pages | 8 | | innodb_stats_transient_sample_pages | 8 | | innodb_status_output | OFF | | innodb_status_output_locks | OFF | | innodb_strict_mode | OFF | | 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 | OFF | | innodb_undo_directory | . | | innodb_undo_logs | 128 | | innodb_undo_tablespaces | 0 | | innodb_use_atomic_writes | OFF | | innodb_use_fallocate | OFF | | innodb_use_global_flush_log_at_trx_commit | ON | | innodb_use_native_aio | ON | | innodb_use_stacktrace | OFF | | innodb_use_sys_malloc | ON | | innodb_version | 5.6.17-65.0 | | innodb_write_io_threads | 4 | + ------------------------------------------- + ----- ------------------- + 143 lignes dans le set (0.02 sec)
Le nombre de cœurs de la machine est de 8, c’est un
Intel(R) Xeon(R) CPU E3-1246 v3 @ 3.50GHz
à partir de /proc/cpuinfo
Une dernière remarque: Exécuter les requêtes avec les index suggérés par RolandoMYSQLDBA. Les requêtes ont duré environ 11-20 secondes. Je tiens à souligner qu'il est crucial pour moi (ceci est la table principale d'un babillard) que la première requête sur un ID de fil retourne en moins d'une seconde, car il y a plus de 60 000 threads et google-bots explorent en permanence ces discussions.
la source
Réponses:
VOTRE REQUÊTE
À première vue, cette requête ne devrait toucher que 1,1597% (62510 sur 5390146) du tableau. Il devrait être rapide étant donné la distribution de clé de threadid 51506.
VÉRIFICATION DE LA RÉALITÉ
Quelle que soit la version de MySQL (Oracle, Percona, MariaDB) utilisée, aucun d’entre eux ne peut lutter contre un ennemi commun: l’architecture InnoDB.
INDEX CLUSTERED
N'oubliez pas que chaque entrée d'ID de thread est associée à une clé primaire. Cela signifie que lorsque vous lisez l'index, il doit effectuer une recherche de clé primaire dans ClusteredIndex (nommé en interne gen_clust_index) . Dans ClusteredIndex, chaque page InnoDB contient à la fois des données et des informations sur l’index PRIMARY KEY. Voir mon post Best of MyISAM et InnoDB pour plus d'informations.
INDEX REDONDANTS
Vous avez beaucoup de fouillis dans la table car certains index ont les mêmes colonnes de tête. MySQL et InnoDB doivent naviguer à travers le fouillis d'index pour accéder aux nœuds BTREE nécessaires. Vous devriez réduire cet encombrement en exécutant ce qui suit:
Pourquoi dépouiller ces index?
threadid_2
etthreadid_visible_dateline
commencez avec les trois mêmes colonnesthreadid_visible_dateline
n'a pas besoin de postid car c'est la clé primaire et il est intégréCACHING DE TAMPONS
Le pool de mémoire tampon InnoDB met en cache les pages de données et d'index. MyISAM ne met en cache que les pages d'index.
Rien que dans ce domaine, MyISAM ne perd pas de temps à mettre des données en cache. C'est parce qu'il n'est pas conçu pour mettre en cache des données. InnoDB met en cache chaque page de données et page d'index (et sa grand-mère) qu'elle touche. Si votre pool de mémoire tampon InnoDB est trop petit, vous pouvez mettre en cache des pages, invalider des pages et supprimer des pages en une seule requête.
DISPOSITION DE LA TABLE
Vous pouvez gagner de la place dans la rangée en considérant
importthreadid
etimportpostid
. Vous les avez comme BIGINTs. Ils occupent 16 octets dans le ClusteredIndex par ligne.Tu devrais courir ça
Cela recommandera les types de données que ces colonnes devraient être pour l'ensemble de données donné.
CONCLUSION
MyISAM a beaucoup moins à faire face à InnoDB, en particulier dans le domaine de la mise en cache.
Bien que vous ayez révélé la quantité de RAM (
32GB
) et la version de MySQL (Server version: 10.0.12-MariaDB-1~trusty-wsrep-log mariadb.org binary distribution, wsrep_25.10.r4002
), il existe encore d’autres pièces de ce puzzle que vous n’avez pas révélées.my.cnf
Si vous pouvez ajouter ces choses à la question, je peux élaborer davantage.
MISE À JOUR 2014-08-28 11:27 EDT
Vous devriez augmenter le filetage
J'envisagerais de désactiver le cache de la requête (voir mon message récent. Pourquoi query_cache_type est désactivé par défaut à partir de MySQL 5.6? )
Je préserverais le pool de mémoire tampon
Augmentez les threads de purge (si vous utilisez DML sur plusieurs tables)
ESSAIE !!!
la source
@RolandMySQLDBA a donné le bon indice pour répondre à la question. Le problème semble résider dans la requête et pour que les résultats soient restitués, chacun de ces champs doit être lu (en quelque sorte dans la base de données).
J'ai supprimé tous les index sauf le
PRIMARY KEY
, et inséré ce nouvel index:ALTER TABLE newbb_innopost ADD INDEX threadid_visible_dateline_index (threadid,visible,dateline,userid,attach,ipaddress);
Ce lien explique ce qui se passe ici ( index couvrant ): Les champs de la requête qui sont interrogés
postid,attach
peuvent maintenant être extraits de la clé elle-même. Cela évite de vérifier les données réelles et d’utiliser les E / S sur le disque dur.Toutes les requêtes fonctionnent maintenant avec 0,00 secondes .. :)
Merci beaucoup à tous pour votre aide.
Edit : Le problème sous-jacent réel n'est pas résolu, je viens de le contourner avec cette technique. InnoDB a besoin de réparations sérieuses dans ce domaine.
la source
SQL_NO_CACHE
.En fonction de votre requête et de votre table, il semble que vous sélectionniez des données dans une table chronologique. En tant que tel, il se peut que la durée de la requête soit lente car vous insérez simultanément?
Si ces deux choses sont vraies, puis-je suggérer de regarder dans ScaleDB comme une alternative? Vous serez toujours sur MariaDB, juste (peut-être) un moteur plus approprié.
http://www.scaledb.com - Page d'accueil http://www.scaledb.com/download-form.php - notre produit
la source
Les deux moteurs exécuteront la requête beaucoup plus rapidement avec
En effet, il s'agira d'un indice "couvrant" et fonctionnera pratiquement de la même manière (en utilisant l'indice BTree).
De plus, je dirai que ce n'est pas possible pour les deux moteurs sur un serveur "froid":
S'il vous plaît utiliser
SQL_NO_CACHE
chaque fois que vous exécutez des timings - nous ne voulons pas que le cache de requêtes pollue les conclusions.Une autre approche rapide (sans regar de cache I / O):
Utilisez InnoDB et passez de
PRIMARY KEY (postid)
àLa raison en est que toutes les lignes pertinentes seront adjacentes, ce qui nécessitera moins d'E / S, etc. Il
INDEX(postid)
faut resterAUTO_INCREMENT
heureux. Mises en garde: Cela perturbe toutes les clés secondaires - certaines seront plus rapides, d'autres plus lentes.la source
Bien que cela ne soit pas directement applicable à @jollyroger car il a déjà le réglage correct, mais j'ai obtenu une amélioration majeure, en passant
innodb_buffer_pool_size
à 70% de ma RAM, comme expliqué dans Pourquoi myisam est-il plus lent qu'InnodbLe premier
MyISAM
était lent, mais oke. Ensuite, lesInnoDB
choses ont mal tourné, semblable au 100x plus lent dans cette question et après avoir changé le réglageInnoDB
, vous avez obtenu 10x plus vite ensuiteMyISAM
.Mon réglage par défaut était sur 8 Mo, ce qui est beaucoup trop petit.
la source