MariaDB升级10.3到10.9,索引,eq_range_index_dive_limit和EXPLAIN

nr7wwzry  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(50)

我目前正在升级和MariadDB服务器从10.3(10.3.38-MariaDB-0ubuntu0.20.04.1)到10.9(10.9.3-MariaDB-1:10.9.3 +maria~ ubu 2004-log)的过程中
我已经在本地运行了10.9版本一段时间,准备将其放到生产环境中。由于我一直在优化一些较大的查询,我注意到在本地,索引在生产环境中的某些情况下没有使用,它们是。
据我所知,这是这些版本号和一些设置之间的变化和引擎试图“更聪明”的成本使用优化与成本只是前进与表扫描无索引使用.很多的谷歌搜索已经产生的职位:
第一个月
我可能有点过时,但当我运行EXPLAIN时,我看到可能的键,但没有使用,这表明存在某种问题。假设ANALYZE TABLE的任何变体都没有导致索引开始使用。我在升级后的测试生产机器上观察到相同的行为,因为索引使用情况与我在本地看到的情况重复。
我关注的一个帖子是,引擎没有很好地“测量”查询的实际结果,强制索引是唯一的选择。这就是我所关注的-在生产负载下将10.9放入我的生产环境中(这对我来说很难可靠地模拟),并看到速度变慢。
我该怎么办:
1.相信版本号之间的变化,并祈祷放弃索引使用会有更好的表现,或者
1.通过explain运行我所有的查询,并开始在所有地方强制索引(在我意识到发生了什么之前,我就这样做了),因为
1.我甚至不知道如何判断哪一个更好,让引擎决定不使用索引,或者我强制索引。
我想知道你们是如何处理这个问题的,或者是关于调整以获得更多索引使用率的建议?如果使用索引不如表扫描好,我真的会遇到速度变慢吗?
FWIW,我已经上下调整了上面这三个服务器选项的设置值,没有任何改变这个简单的SELECT语句的索引用法。
感谢您的输入,下面的上下文。

MariaDB [pweb]> EXPLAIN extended select * from `accounting_transactions` where `accounting_transactions`.`cr_account` = 'f7d78ef5-ca59-44d1-9d67-70a83960f473' \G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: accounting_transactions
         type: ALL
possible_keys: accounting_transactions_cr_account_index
          key: NULL
      key_len: NULL
          ref: NULL
         rows: 532030
     filtered: 35.63
        Extra: Using where
1 row in set, 1 warning (0.002 sec)
MariaDB [pweb]> EXPLAIN extended select * from `accounting_transactions` force index (accounting_transactions_cr_account_index ) where `accounting_transactions`.`cr_account` = 'f7d78ef5-ca59-44d1-9d67-70a83960f473'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: accounting_transactions
         type: ref
possible_keys: accounting_transactions_cr_account_index
          key: accounting_transactions_cr_account_index
      key_len: 144
          ref: const
         rows: 189558
     filtered: 100.00
        Extra: Using index condition
1 row in set, 1 warning (0.001 sec)
MariaDB [pweb]> SELECT VERSION();
+-------------------------------------------+
| VERSION()                                 |
+-------------------------------------------+
| 10.9.3-MariaDB-1:10.9.3+maria~ubu2004-log |
+-------------------------------------------+
1 row in set (0.001 sec)
MariaDB [pweb]> show create table accounting_transactions \G
*************************** 1. row ***************************
       Table: accounting_transactions
Create Table: CREATE TABLE `accounting_transactions` (
  `id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
  `event_id` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  `dr_account` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
  `cr_account` char(36) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  `deleted_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `accounting_transactions_event_id_index` (`event_id`),
  KEY `accounting_transactions_dr_account_index` (`dr_account`),
  KEY `accounting_transactions_cr_account_index` (`cr_account`),
  CONSTRAINT `accounting_transactions_cr_account_foreign` FOREIGN KEY (`cr_account`) REFERENCES `accounting_accounts` (`id`),
  CONSTRAINT `accounting_transactions_dr_account_foreign` FOREIGN KEY (`dr_account`) REFERENCES `accounting_accounts` (`id`),
  CONSTRAINT `accounting_transactions_event_id_foreign` FOREIGN KEY (`event_id`) REFERENCES `accounting_events` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
1 row in set (0.002 sec)
MariaDB [pweb]> SHOW variables LIKE '%query_cache%';
+------------------------------+----------+
| Variable_name                | Value    |
+------------------------------+----------+
| have_query_cache             | YES      |
| query_cache_limit            | 1048576  |
| query_cache_min_res_unit     | 4096     |
| query_cache_size             | 16777216 |
| query_cache_strip_comments   | OFF      |
| query_cache_type             | OFF      |
| query_cache_wlock_invalidate | OFF      |
+------------------------------+----------+
7 rows in set (0.002 sec)
MariaDB [pweb]> SHOW variables where Variable_name in ('eq_range_index_dive_limit', 'use_stat_tables', 'sort_buffer_size')\G
*************************** 1. row ***************************
Variable_name: eq_range_index_dive_limit
        Value: 100000000
*************************** 2. row ***************************
Variable_name: sort_buffer_size
        Value: 209715200
*************************** 3. row ***************************
Variable_name: use_stat_tables
        Value: NEVER
3 rows in set (0.002 sec)

在某些基于实际查询时间的情况下-我注意到没有使用索引的情况下返回速度更快,我不得不说这是非常令人惊讶的。

ws51t4hk

ws51t4hk1#

91785/538368 --使用了表格的17%。
当读取表的大部分内容时,进行表扫描 * 通常 * 会更快。当使用索引时,它需要在索引的BTree和数据的BTree之间来回反弹。这种反弹 * 可能 * 比简单地对数据进行线性扫描需要更长的时间,从而抛出83%的行。
唉,优化器没有足够的统计数据来说明哪种方式更快。
在这种情况下,结果集的大小可能太大,无法放入查询缓存。因此,即使启用了查询缓存,尝试使用QC也可能会导致额外的开销。
你可以做的一件事是缩小CHAR(36)字符串。要么使用UUID数据类型,要么至少将它们压缩为BINARY(16)。我的UUIDs博客甚至在数据类型存在之前就讨论过这一点。
客户端到底要对91785行做什么呢?另一个提示:如果客户端没有使用所有的列,只拼出必要的列,而不是使用SELECT *

相关问题