gpt4 book ai didi

mysql - 相同的执行路径、数据和原理图;不同的查询时间

转载 作者:可可西里 更新时间:2023-11-01 06:30:40 25 4
gpt4 key购买 nike

我们已经注意到我们的 MySQL 性能在查询时间上存在一些不一致的情况,我们认为这不能仅用服务器负载来解释。尽管具有类似的设置,但某些查询似乎比其他查询更有效。

编辑:自从打开这个问题,我们的数据库崩溃了(目前未知原因,RDS 团队正在调查),重启后问题不再重现,查询速度相同。我仍然想知道出了什么问题,因为问题可能会再次出现,但也许我们永远不会发现......

继续原始问题:为了测试这一点,我制作了一张表格的近副本。尽管具有相同的执行路径、相同的数据和非常相似的表示意图,但针对复制表的性能(查询时间)明显比源差。

在这个例子中,我们有以下 3 个表:

  • offer_clicks
  • 提供
  • 提供_新

  • “offers_new”是一个测试表,它的字段数量有限(只有“id”和“status”字段),但在其他方面与“offers”表具有相同的结构(也有“id”和“status”)字段,还有许多其他字段)。以下是表格示意图:

    优惠表:
    | offers | CREATE TABLE `offers` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `status` tinyint(4) NOT NULL DEFAULT '0',
    `user_id` int(11) NOT NULL DEFAULT '0',
    .....many_other_fields.....
    KEY `ix_public_view_key` (`public_view_key`),
    FULLTEXT KEY `name` (`name`,`internal_name`)
    ) ENGINE=InnoDB AUTO_INCREMENT=18425582 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

    新表:
    | offers_new | CREATE TABLE `offers_new` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `status` tinyint(4) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=18423831 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |

    然后我们做了一个从“offers”表到“offers_new”表的插入选择:
    INSERT INTO offers_new (id, status) SELECT id, status FROM offers;
    在此之后,我们开始运行一些测试查询。如您所见,“offers_new”表的查询时间比“offers”表慢约 10 倍。
    mysql> SELECT COUNT(*) FROM offers_clicks, offers_new WHERE offers_new.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----------+
    | COUNT(*) |
    +----------+
    | 15472 |
    +----------+
    1 row in set (26.04 sec)

    mysql> SELECT COUNT(*) FROM offers_clicks, offers WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----------+
    | COUNT(*) |
    +----------+
    | 15472 |
    +----------+
    1 row in set (2.90 sec)

    mysql> SELECT COUNT(*) FROM offers_clicks, offers_new WHERE offers_new.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----------+
    | COUNT(*) |
    +----------+
    | 15472 |
    +----------+
    1 row in set (28.07 sec)

    mysql> SELECT COUNT(*) FROM offers_clicks, offers WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----------+
    | COUNT(*) |
    +----------+
    | 15472 |
    +----------+
    1 row in set (2.26 sec)

    请注意,两个查询的执行路径完全相同:
    mysql> explain SELECT COUNT(*) FROM offers_clicks, offers_new WHERE offers_new.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----+-------------+---------------+-----------------------------------------------------------------------+--------+--------------------+---------+---------+--------------------------------------------+-------+----------+-----------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+
    | 1 | SIMPLE | offers_clicks | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19 | range | pts_id,date,date_2 | date | 5 | NULL | 15472 | 100.00 | Using index condition |
    | 1 | SIMPLE | offers_new | NULL | eq_ref | PRIMARY | PRIMARY | 4 | dejong_pointstoshop.offers_clicks.offer_id | 1 | 100.00 | Using index |
    +----+
    2 rows in set, 1 warning (0.00 sec)

    mysql> explain SELECT COUNT(*) FROM offers_clicks, offers WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00';
    +----+-------------+---------------+-----------------------------------------------------------------------+--------+--------------------+---------+---------+--------------------------------------------+-------+----------+-----------------------+
    | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
    +----+-------------+---------------+-----------------------------------------------------------------------+--------+--------------------+---------+---------+--------------------------------------------+-------+----------+-----------------------+
    | 1 | SIMPLE | offers_clicks | p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19 | range | pts_id,date,date_2 | date | 5 | NULL | 15472 | 100.00 | Using index condition |
    | 1 | SIMPLE | offers | NULL | eq_ref | PRIMARY | PRIMARY | 4 | dejong_pointstoshop.offers_clicks.offer_id | 1 | 100.00 | Using index |
    +----+-------------+---------------+-----------------------------------------------------------------------+--------+--------------------+---------+---------+--------------------------------------------+-------+----------+-----------------------+
    2 rows in set, 1 warning (0.00 sec)

    我们在此之后采取的步骤:
  • 我们联系了我们的主机 AWS,看看我们的 RDS 设置是否有任何问题。他们报告说他们找不到任何错误,并声称 MySQL
  • 一定有问题
  • 我们运行分析以查看内部发生的情况。我们没有看到交换、主要页面错误(仅次要)或其他可以解释差异的事情。我已在本主题底部附上了数据。
  • 我们确保优化表以确保没有以某种方式对表造成不良碎片,即使这在新表上似乎不太可能。
  • 我们试图通过在计时之前多次加载查询来确保“offers_new”表是“热的”
  • 我们在暂存环境中运行这些查询并看到性能相同(“offers_new”表稍快,可能是因为字段较少)

  • 我们使用的是 MySQL 8.0.15

    值得注意的是,我们的生产系统处于高 CPU 负载下。但是,这不应解释几乎相同的查询的不同查询时间。我们现在运行了几十次,结果都是一样的。

    还值得注意的是,“offers”表是一个生产表,因此它经常被更新/查询。 “offers_new”,这是慢表,不是。

    基于评论的编辑:
  • ANSI JOIN 具有相同的结果
  • 就像一位评论者一样,我们认为内存中可能没有“offers_new”的内容。毕竟,“offers_new”没有用于生产,而“offers”是。但是,分析显示两个查询的“Page_faults_major”都为 0。虽然我们在这方面的理解相当有限,但我们认为这意味着数据是从内存而不是磁盘加载的。
  • 一位评论者要求我们仅对“offers”和“offers_new”表运行 COUNT。结果如下:
  • mysql> SELECT COUNT(*) FROM offers_new;
    +----------+
    | COUNT(*) |
    +----------+
    | 5093127 |
    +----------+
    1 row in set (0.13 sec)

    mysql> SELECT COUNT(*) FROM offers;
    +----------+
    | COUNT(*) |
    +----------+
    | 5107742 |
    +----------+
    1 row in set (2.54 sec)

    计数非常接近。 Offers 是一个实时表,所以自从我昨天测试以来,新条目已添加到表中。尽管如此,计数仍然很接近。有趣的是,“offers_new”上的 COUNT(*) 明显比“offers”快,所以与我们提出这个问题的查询结果相反!计数“offers_new”大约是 0.1/0.2 秒,计数“offers”表是几秒(范围在 2-6s 之间)。我每次运行它大约 10 次,以确保它不仅仅是服务器负载,而且它始终较慢。我认为这与列数有关,列数对于“报价”表来说要高得多。无论哪种方式,看到另一个查询的相反结果都很有趣......

    这是分析:
    mysql> SHOW PROFILES;
    +----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    | Query_ID | Duration | Query |
    +---+
    | 1 | 26.03997750 | SELECT COUNT(*) FROM offers_clicks, offers_new WHERE offers_new.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00' |
    | 2 | 2.89890600 | SELECT COUNT(*) FROM offers_clicks, offers WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00' |
    | 3 | 28.07228225 | SELECT COUNT(*) FROM offers_clicks, offers_new WHERE offers_new.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00' |
    | 4 | 2.25160675 | SELECT COUNT(*) FROM offers_clicks, offers WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date > '2019-05-30 00:00:00' and offers_clicks.date < '2019-05-30 01:00:00' |
    +----------+-------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
    4 rows in set, 1 warning (0.00 sec)

    mysql> SHOW PROFILE ALL FOR QUERY 1;
    +---+
    | Status | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out | Messages_sent | Messages_received | Page_faults_major | Page_faults_minor | Swaps | Source_function | Source_file | Source_line |
    +---+
    | starting | 0.000364 | 0.016000 | 0.000000 | 3 | 3 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | NULL | NULL | NULL |
    | Executing hook on transaction | 0.000134 | 0.008000 | 0.000000 | 6 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | launch_hook_trans_begin | rpl_handler.cc | 1100 |
    | starting | 0.000128 | 0.008000 | 0.000000 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | launch_hook_trans_begin | rpl_handler.cc | 1102 |
    | checking permissions | 0.000173 | 0.008000 | 0.000000 | 3 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | check_access | sql_authorization.cc | 1899 |
    | checking permissions | 0.000182 | 0.012000 | 0.000000 | 65 | 33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | check_access | sql_authorization.cc | 1899 |
    | Opening tables | 0.003432 | 0.176000 | 0.012000 | 556 | 224 | 0 | 0 | 0 | 0 | 0 | 20 | 0 | open_tables | sql_base.cc | 5586 |
    | init | 0.000235 | 0.012000 | 0.000000 | 25 | 20 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | execute | sql_select.cc | 555 |
    | System lock | 0.000151 | 0.008000 | 0.000000 | 62 | 17 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 332 |
    | optimizing | 0.000171 | 0.008000 | 0.000000 | 32 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize | sql_optimizer.cc | 212 |
    | statistics | 0.001255 | 0.068000 | 0.000000 | 230 | 125 | 0 | 24 | 0 | 0 | 0 | 0 | 0 | optimize | sql_optimizer.cc | 425 |
    | preparing | 0.000166 | 0.012000 | 0.000000 | 43 | 19 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | optimize | sql_optimizer.cc | 499 |
    | executing | 0.000134 | 0.004000 | 0.000000 | 27 | 16 | 0 | 0 | 0 | 0 | 0 | 10 | 0 | exec | sql_executor.cc | 197 |
    | Sending data | 26.032492 | 999.999999 | 67.940000 | 5361975 | 1420548 | 227416 | 1584568 | 0 | 0 | 0 | 299459 | 0 | exec | sql_executor.cc | 273 |
    | end | 0.000325 | 0.012000 | 0.000000 | 7 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | execute | sql_select.cc | 608 |
    | query end | 0.000115 | 0.004000 | 0.000000 | 11 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_execute_command | sql_parse.cc | 4581 |
    | waiting for handler commit | 0.000118 | 0.008000 | 0.000000 | 34 | 13 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ha_commit_trans | handler.cc | 1533 |
    | closing tables | 0.000118 | 0.004000 | 0.000000 | 23 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_execute_command | sql_parse.cc | 4627 |
    | freeing items | 0.000163 | 0.008000 | 0.000000 | 4 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_parse | sql_parse.cc | 5256 |
    | cleaning up | 0.000125 | 0.008000 | 0.000000 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 2108 |
    +---+
    19 rows in set, 1 warning (0.00 sec)

    mysql> SHOW PROFILE ALL FOR QUERY 2;
    +---+
    | Status | Duration | CPU_user | CPU_system | Context_voluntary | Context_involuntary | Block_ops_in | Block_ops_out | Messages_sent | Messages_received | Page_faults_major | Page_faults_minor | Swaps | Source_function | Source_file | Source_line |
    +---+
    | starting | 0.000364 | 0.012000 | 0.000000 | 41 | 24 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NULL | NULL | NULL |
    | Executing hook on transaction | 0.000137 | 0.008000 | 0.000000 | 40 | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | launch_hook_trans_begin | rpl_handler.cc | 1100 |
    | starting | 0.000135 | 0.004000 | 0.000000 | 21 | 6 | 0 | 16 | 0 | 0 | 0 | 2 | 0 | launch_hook_trans_begin | rpl_handler.cc | 1102 |
    | checking permissions | 0.000124 | 0.008000 | 0.000000 | 26 | 7 | 0 | 16 | 0 | 0 | 0 | 2 | 0 | check_access | sql_authorization.cc | 1899 |
    | checking permissions | 0.000139 | 0.008000 | 0.000000 | 19 | 9 | 32 | 24 | 0 | 0 | 0 | 4 | 0 | check_access | sql_authorization.cc | 1899 |
    | Opening tables | 0.000152 | 0.004000 | 0.000000 | 30 | 14 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | open_tables | sql_base.cc | 5586 |
    | init | 0.000125 | 0.004000 | 0.008000 | 25 | 19 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | execute | sql_select.cc | 555 |
    | System lock | 0.000237 | 0.004000 | 0.004000 | 26 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 332 |
    | optimizing | 0.000150 | 0.008000 | 0.000000 | 24 | 7 | 0 | 0 | 0 | 0 | 0 | 4 | 0 | optimize | sql_optimizer.cc | 212 |
    | statistics | 0.001082 | 0.048000 | 0.004000 | 192 | 59 | 0 | 0 | 0 | 0 | 0 | 17 | 0 | optimize | sql_optimizer.cc | 425 |
    | preparing | 0.000162 | 0.008000 | 0.000000 | 19 | 22 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize | sql_optimizer.cc | 499 |
    | executing | 0.000136 | 0.008000 | 0.000000 | 33 | 32 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | exec | sql_executor.cc | 197 |
    | Sending data | 2.894895 | 120.524000 | 6.512000 | 551014 | 158606 | 43632 | 125120 | 0 | 0 | 0 | 34154 | 0 | exec | sql_executor.cc | 273 |
    | end | 0.000359 | 0.012000 | 0.000000 | 28 | 27 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | execute | sql_select.cc | 608 |
    | query end | 0.000130 | 0.004000 | 0.004000 | 51 | 33 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_execute_command | sql_parse.cc | 4581 |
    | waiting for handler commit | 0.000135 | 0.004000 | 0.000000 | 58 | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ha_commit_trans | handler.cc | 1533 |
    | closing tables | 0.000144 | 0.008000 | 0.000000 | 27 | 15 | 0 | 16 | 0 | 0 | 0 | 2 | 0 | mysql_execute_command | sql_parse.cc | 4627 |
    | freeing items | 0.000165 | 0.008000 | 0.000000 | 23 | 4 | 0 | 8 | 0 | 0 | 0 | 3 | 0 | mysql_parse | sql_parse.cc | 5256 |
    | cleaning up | 0.000137 | 0.008000 | 0.000000 | 6 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 2108 |
    +---+
    19 rows in set, 1 warning (0.00 sec)
    mysql> show create table offers \G
    *************************** 1. row ***************************
    Table: offers
    Create Table: CREATE TABLE `offers` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `status` tinyint(4) NOT NULL DEFAULT '0',
    `field_a` int(11) NOT NULL DEFAULT '0',
    `field_b` text COLLATE utf8_unicode_ci NOT NULL,
    `field_c` varchar(150) COLLATE utf8_unicode_ci NOT NULL,
    `field_d` text COLLATE utf8_unicode_ci NOT NULL,
    `field_e` text COLLATE utf8_unicode_ci NOT NULL,
    `field_f` text COLLATE utf8_unicode_ci,
    `field_g` varchar(64) CHARACTER SET utf8 DEFAULT NULL,
    `field_h` text COLLATE utf8_unicode_ci,
    `field_i` mediumint(9) NOT NULL DEFAULT '0',
    `field_j` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
    `field_k` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
    `field_l` decimal(10,4) NOT NULL,
    `field_m` decimal(10,4) NOT NULL DEFAULT '0.0000',
    `field_n` decimal(10,4) NOT NULL DEFAULT '0.0000',
    `field_o` decimal(10,4) NOT NULL DEFAULT '0.0000',
    `field_p` decimal(5,2) NOT NULL DEFAULT '0.00',
    `field_q` text COLLATE utf8_unicode_ci NOT NULL,
    `field_r` text COLLATE utf8_unicode_ci NOT NULL,
    `field_s` int(11) NOT NULL,
    `field_t` mediumint(9) NOT NULL DEFAULT '0',
    `field_u` tinyint(4) NOT NULL DEFAULT '0',
    `field_v` tinyint(4) NOT NULL DEFAULT '0',
    `field_w` tinyint(4) NOT NULL DEFAULT '0',
    `field_x` tinyint(4) NOT NULL,
    `field_y` tinyint(4) DEFAULT NULL,
    `field_z` tinyint(4) NOT NULL DEFAULT '0',
    `field_aa` tinyint(1) NOT NULL DEFAULT '0',
    `field_ab` tinyint(1) NOT NULL,
    `field_ac` tinyint(4) NOT NULL,
    `field_ad` tinyint(1) NOT NULL DEFAULT '0',
    `field_ae` tinyint(1) NOT NULL,
    `field_af` int(10) unsigned DEFAULT '0',
    `field_ag` int(10) unsigned NOT NULL,
    `field_ah` int(10) unsigned NOT NULL,
    `field_ai` int(11) NOT NULL,
    `field_aj` tinyint(1) NOT NULL DEFAULT '0',
    `field_ak` decimal(6,3) DEFAULT '0.000',
    `field_al` tinyint(1) NOT NULL,
    `field_am` decimal(8,3) NOT NULL,
    `field_an` decimal(8,3) NOT NULL,
    `field_ao` decimal(5,2) NOT NULL,
    `field_ap` decimal(8,3) NOT NULL,
    `field_aq` tinyint(3) unsigned DEFAULT NULL,
    `field_ar` int(11) NOT NULL,
    `field_as` mediumint(9) NOT NULL DEFAULT '0',
    `field_at` mediumint(9) NOT NULL,
    `field_au` mediumint(9) NOT NULL,
    `field_av` mediumint(9) NOT NULL,
    `field_aw` mediumint(9) NOT NULL,
    `field_ax` mediumint(9) NOT NULL DEFAULT '8388607',
    `field_ay` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
    `field_az` tinyint(1) NOT NULL DEFAULT '0',
    `field_ba` smallint(5) unsigned DEFAULT NULL,
    `field_bb` tinyint(1) NOT NULL DEFAULT '0',
    `field_bc` tinyint(1) NOT NULL DEFAULT '0',
    `field_bd` tinyint(1) NOT NULL DEFAULT '1',
    `field_be` tinyint(1) NOT NULL,
    `field_bf` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
    `field_bg` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `field_bh` tinyint(1) NOT NULL DEFAULT '0',
    `field_bi` text COLLATE utf8_unicode_ci NOT NULL,
    `field_bj` tinyint(1) NOT NULL DEFAULT '0',
    `field_bk` date DEFAULT NULL,
    `field_bl` date DEFAULT NULL,
    `field_bm` varchar(20) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
    `field_bn` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
    `field_bo` tinyint(1) NOT NULL DEFAULT '0',
    `field_bp` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
    `field_bq` smallint(5) unsigned DEFAULT NULL,
    `field_br` tinyint(3) unsigned NOT NULL DEFAULT '0',
    `field_bs` decimal(10,6) DEFAULT NULL,
    `field_bt` decimal(10,6) DEFAULT NULL,
    `field_bu` tinyint(1) NOT NULL DEFAULT '0',
    `field_bv` tinyint(1) NOT NULL DEFAULT '0',
    `field_bw` tinyint(1) NOT NULL DEFAULT '0',
    `field_bx` tinyint(1) NOT NULL DEFAULT '0',
    `field_by` tinyint(1) NOT NULL DEFAULT '0',
    `field_bz` datetime DEFAULT NULL,
    `field_ca` datetime DEFAULT NULL,
    `field_cb` datetime DEFAULT NULL,
    `field_cc` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
    `field_cd` datetime DEFAULT NULL,
    `field_ce` varchar(155) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
    `field_cf` int(11) DEFAULT NULL,
    `field_cg` decimal(10,4) NOT NULL DEFAULT '0.0000',
    `field_ch` tinyint(1) NOT NULL DEFAULT '0',
    `field_ci` decimal(5,4) NOT NULL DEFAULT '0.0000',
    `field_cj` mediumint(9) NOT NULL DEFAULT '0',
    `field_ck` datetime DEFAULT NULL,
    `field_cl` tinyint(1) NOT NULL DEFAULT '0',
    `field_cm` datetime DEFAULT NULL,
    `field_cn` smallint(5) unsigned NOT NULL DEFAULT '0',
    `field_co` smallint(5) unsigned NOT NULL DEFAULT '0',
    `field_cp` tinyint(1) NOT NULL DEFAULT '0',
    `field_cq` tinyint(1) NOT NULL DEFAULT '0',
    `field_cr` tinyint(1) NOT NULL DEFAULT '0',
    `field_cs` tinyint(1) NOT NULL DEFAULT '0',
    `field_ct` tinyint(1) NOT NULL DEFAULT '0',
    `field_cu` tinyint(1) NOT NULL DEFAULT '0',
    `field_cv` tinyint(1) NOT NULL DEFAULT '0',
    `field_cw` tinyint(1) NOT NULL DEFAULT '0',
    `field_cx` decimal(5,2) NOT NULL,
    `field_cy` tinyint(1) NOT NULL DEFAULT '0',
    `field_cz` tinyint(1) NOT NULL DEFAULT '0',
    `field_da` int(11) NOT NULL DEFAULT '0',
    `field_db` tinyint(1) NOT NULL DEFAULT '0',
    `field_dc` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
    `field_dd` tinyint(3) unsigned DEFAULT NULL,
    `field_de` tinyint(1) DEFAULT '0',
    `field_df` datetime DEFAULT NULL,
    `field_dg` tinyint(1) NOT NULL DEFAULT '0',
    `field_dh` tinyint(1) NOT NULL DEFAULT '0',
    `⁠⁠⁠⁠field_di` bigint(20) DEFAULT NULL,
    `field_dj` datetime DEFAULT NULL,
    `field_dk` tinyint(1) NOT NULL DEFAULT '0',
    `field_dl` int(1) DEFAULT NULL,
    `field_dm` tinyint(1) NOT NULL DEFAULT '0',
    `field_dn` int(11) NOT NULL DEFAULT '0',
    `field_do` tinyint(1) NOT NULL DEFAULT '0',
    `field_dp` tinyint(3) unsigned NOT NULL DEFAULT '0',
    `field_dq` int(11) NOT NULL DEFAULT '0',
    `field_dr` json DEFAULT NULL,
    `field_ds` int(11) NOT NULL DEFAULT '0',
    `field_dt` datetime DEFAULT NULL,
    `field_du` tinyint(1) NOT NULL DEFAULT '0',
    `field_dv` json NOT NULL,
    `field_dw` decimal(8,5) DEFAULT '0.00000',
    `field_dx` tinyint(1) NOT NULL DEFAULT '0',
    `field_dy` smallint(6) NOT NULL DEFAULT '14',
    PRIMARY KEY (`id`),
    UNIQUE KEY `field_i_field_j` (`field_i`,`field_j`),
    UNIQUE KEY `field_j_field_i` (`field_k`,`field_i`),
    KEY `status_field_bf` (`status`,`field_bf`),
    KEY `field_bm` (`field_bm`),
    KEY `status_field_i_field_bo` (`status`,`field_i`,`field_bo`),
    KEY `field_j` (`field_j`),
    KEY `field_bz` (`field_bz`),
    KEY `field_br` (`field_br`),
    KEY `field_bh` (`field_bh`),
    KEY `field_ba` (`field_ba`),
    KEY `field_cm` (`status`,`field_cm`),
    KEY `field_cc` (`field_cc`),
    KEY `field_i_field_cc` (`field_i`,`field_cc`),
    KEY `field_g` (`field_g`),
    FULLTEXT KEY `field_c` (`field_c`,`field_ce`)
    ) ENGINE=InnoDB AUTO_INCREMENT=18425582 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

    最佳答案

    猜测(等待评论中要求的更多信息)...

  • innodb_buffer_pool_size 小于 Data_length (请参阅 SHOW TABLE SIZE offers ),并且 15K 行分散在表格周围。这可能会导致命中磁盘而不是找到所需的 id在缓存 (buffer_pool) 中。
  • 比例约为 10:1 以两对运行为例,这是我在比较命中磁盘和缓存中的查询时多次看到的情况。

  • 部分解决方案可能是 增加buffer_pool .但是,由于您使用的是云服务,因此增加费用的唯一方法可能是支付 费用。更大的内存 .

    另一种方法可能是强制或欺骗它使用 不同索引 .但首先我需要查看其余的索引,以及索引列的数据类型。

    同时,我真的很想批评 offers_clicks ;什么是分区键?

    另一种方法......这是一个常见的查询吗?似乎是“一小时内发生了多少次点击?”

    为什么需要看 offers吗根本?难道不能从 SELECT COUNT(*) FROM offers_clicks WHERE date ...得到正确的答案吗? ?

    如果您确实需要 JOIN ,那么我们来谈谈构建和维护一个 summary table保持每小时的计数。

    附带问题
    FROM offers_clicks, offers
    WHERE offers.id = offers_clicks.offer_id AND offers_clicks.date

    应该写
    FROM offers_clicks
    JOIN offers ON offers.id = offers_clicks.offer_id -- how the tables relate
    WHERE offers_clicks.date ...

    前者是 JOIN的老式“commalist”风格,后者是 首选语法 .这两种语法生成相同的代码,因此这不是性能问题。前者看起来像“交叉连接”,但 WHERE使它有效地不是。

    还有...这只是3599秒, 不是一个小时 .约定将包括第一个午夜。
        date > '2019-05-30 00:00:00'
    and date < '2019-05-30 01:00:00'

    我更喜欢这种风格,因为它避免了闰年问题等:
        date >= '2019-05-30 00:00:00'
    and date < '2019-05-30 00:00:00' + INTERVAL 1 HOUR

    页面错误 ...

    当程序(MySQL 或任何其他程序)分配的内存 (RAM) 超过操作系统愿意提供的内存时,一些页面(通常大小为 4KB)将“交换”到磁盘。当程序引用页面时,会发生“页面错误”。这是一个硬件中断,显示“ panic !您要求的页面在 RAM 中没有”。然后操作系统介入将该页面复制回 RAM,以便程序可以继续。

    InnoDB 更愿意布置大量 RAM,然后可以随时免费访问所有 RAM。也就是说,InnoDB 假装永远不会发生页面错误。因此, 页面错误严重影响性能 .不要将 MySQL 配置为使用“过多”RAM,否则会出现页面错误。

    InnoDB 确实需要将数据块和索引(以及表定义等)交换到 RAM 中,并为其他块释放空间。但是 InnoDB 是经过精心设计和编码的,以尽量减少这种情况。 “缓冲池”是一大块 RAM,InnoDB 将其用作其 16KB 块的 LRU(最近最少使用)缓存。这可能是导致处理速度变慢的原因,而不是 CPU,而不是页面错误等(我等待一些信息,以便我可以确认这一点。)

    The first time is usually slower, which is when it shows major page faults. Follow up queries are usually fast.



    这意味着有 I/O 来引入查询所需的页面(主要页面错误)。然后可以在没有 I/O 的情况下运行后续查询(更快)。

    而且,由于 offers大得多,会有更多的 I/O。然而,这与你所看到的相反。

    关于mysql - 相同的执行路径、数据和原理图;不同的查询时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56397652/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com