MySQL/MariaDB 查询在某些 table 条件下缓慢的可能原因
Possible causes that a MySQL/MariaDB query is slow under some table conditions
我遇到了 st运行ge 问题,在某些情况下查询速度慢:
我做了一些测试,并且能够将问题隔离到一个名为 products_description
的 table(所有 table 都是 MyISAM)。
起初我注意到当这个 table 是新的(即刚刚导入的)时,查询总是执行得很快(~0.3s)。
但是,如果我在任何时候(甚至在导入后立即)对此特定 table 执行任何这些操作:
CHECK
、OPTIMIZE
、ANALYZE
或 REPAIR
,查询突然减慢 x10 倍(大约需要 4.5 秒)并且一直保持缓慢。
请注意,我在 运行 查询时强制不缓存以确保结果正确。
只有当我对 table:
执行任何这些操作时,我才能恢复性能
1) DROP
table 并再次导入。
或
2) ALTER
以下任何一项 table:Collation
或 CHECKSUM
或 DELAY_KEY_WRITE
。然后它以更改后的值快速运行,当恢复到旧值时,性能仍然很快。
或者可以执行 ALTER products_description FORCE
来恢复性能。
即便如此,如果我对 table 执行任何 CHECK
、OPTIMIZE
、ANALYZE
或 REPAIR
操作,查询速度也会下降直到我执行 1) 或 2)
我测试的另一件事:
在对 table 执行任何操作之前,我备份了 table 的文件(products_description.frm
、products_description.MYD
、products_description.MYI
)、运行查询,它运行快。然后我在table上执行CHECK
,运行查询,速度慢了10倍,我复制了备份文件并覆盖了3个文件,再次运行查询, 再次慢速.
我已经将数据库压缩到一个 ~5mb 的 zip 文件中(~80mb 解压缩)。
如果有人想在你自己的环境下测试数据库,请告诉我,我会发给你下载link。我可以在 MariaDB 10.1+ 和 MySQL 5.6+.
的几个不同服务器上重现它
这是我 运行 的 SQL 查询,您应该使用以下方法进行测试:
SELECT DISTINCT pav.products_options_values_id,
pav.products_options_values_name,
pav.products_options_values_sort_order
FROM products_stock ps,
products_options_values pav,
(SELECT DISTINCT pa.products_id
FROM products_attributes pa,
products_options_values pov,
(SELECT p.products_id,
p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL)
AS
specials_new_products_price,
IF(s.status, s.specials_new_products_price,
p.products_price) AS
final_price,
IF(p.clearance_price < p.products_cost * 2.25,
p.clearance_price,
p.products_cost * 2.25)
AS
sorting_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_description pd
ON p.products_id = pd.products_id
WHERE
/*FASTIDS*/
p.products_status = '1'
AND Date_sub('2016-04-19', INTERVAL 7000 day) <=
p.products_date_added
) m
WHERE m.products_id = pa.products_id
AND pa.options_id = 1
AND pa.options_values_id = pov.products_options_values_id
AND pov.language_id = '1') q
WHERE q.products_id = ps.products_id
AND ps.products_stock_attributes =
Concat('1-', pav.products_options_values_id)
AND ps.products_stock_quantity > 0
ORDER BY pav.products_options_values_sort_order ASC
这是 EXPLAIN EXTENDED 结果。似乎优化器在两个 table 上的工作方式不同,但这并不能真正解释为什么会发生这种情况,因为复制的数据库应该是相同的。
这些是对慢速和快速数据库的查询分析的屏幕截图:
造成这种巨大差异的可能原因是什么?如何验证和解决这些问题?
编辑:
根据评论中的要求,这些是显示表:
CREATE TABLE IF NOT EXISTS `products` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`products_quantity` int(4) NOT NULL DEFAULT '0',
`products_model` bigint(20) DEFAULT NULL,
`products_image` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_med` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_lrg` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bimage` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`clearance_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_cost` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_rmb_cost` decimal(7,2) DEFAULT NULL,
`products_best_rmb` decimal(7,2) DEFAULT NULL,
`products_thb_flag` tinyint(1) NOT NULL DEFAULT '0',
`products_date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`products_last_modified` datetime DEFAULT NULL,
`products_date_available` datetime DEFAULT NULL,
`products_weight` decimal(5,2) NOT NULL DEFAULT '0.00',
`products_length` decimal(5,2) NOT NULL DEFAULT '0.00',
`products_width` decimal(5,2) DEFAULT '0.00',
`products_height` decimal(5,2) DEFAULT '0.00',
`products_status` tinyint(1) NOT NULL DEFAULT '0',
`products_tax_class_id` int(11) NOT NULL DEFAULT '0',
`manufacturers_id` int(11) DEFAULT NULL,
`products_ordered` int(11) NOT NULL DEFAULT '0',
`products_parent_id` int(11) NOT NULL DEFAULT '0',
`products_price1` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price2` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price3` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price4` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price5` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price6` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price7` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price8` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price9` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price10` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price11` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price1_qty` int(11) NOT NULL DEFAULT '0',
`products_price2_qty` int(11) NOT NULL DEFAULT '0',
`products_price3_qty` int(11) NOT NULL DEFAULT '0',
`products_price4_qty` int(11) NOT NULL DEFAULT '0',
`products_price5_qty` int(11) NOT NULL DEFAULT '0',
`products_price6_qty` int(11) NOT NULL DEFAULT '0',
`products_price7_qty` int(11) NOT NULL DEFAULT '0',
`products_price8_qty` int(11) NOT NULL DEFAULT '0',
`products_price9_qty` int(11) NOT NULL DEFAULT '0',
`products_price10_qty` int(11) NOT NULL DEFAULT '0',
`products_price11_qty` int(11) NOT NULL DEFAULT '0',
`products_qty_blocks` int(11) NOT NULL DEFAULT '1',
`products_group_access` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'G,0',
`products_nav_access` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'G,0',
`sort_order` smallint(3) NOT NULL DEFAULT '0',
`vendors_id` int(11) DEFAULT '1',
`vendors_product_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`vendors_prod_id` varchar(24) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`vendors_prod_comments` mediumtext COLLATE utf8_unicode_ci,
`products_qty_days` smallint(4) NOT NULL DEFAULT '0',
`products_qty_years` smallint(4) NOT NULL DEFAULT '0',
`products_quantity_order_min` int(8) NOT NULL DEFAULT '1',
`products_quantity_order_units` int(8) NOT NULL DEFAULT '1',
`products_price_list` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price_rebate` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount1` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount2` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount3` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount4` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount1_qty` int(6) NOT NULL DEFAULT '0',
`products_discount2_qty` int(6) NOT NULL DEFAULT '0',
`products_discount3_qty` int(6) NOT NULL DEFAULT '0',
`products_discount4_qty` int(6) NOT NULL DEFAULT '0',
`products_discounts_id` int(11) NOT NULL DEFAULT '0',
`products_priced_by_attribute` tinyint(1) NOT NULL DEFAULT '0',
`product_is_free` tinyint(1) NOT NULL DEFAULT '0',
`product_is_call` tinyint(1) NOT NULL DEFAULT '0',
`products_quantity_mixed` tinyint(1) NOT NULL DEFAULT '0',
`product_is_showroom_only` tinyint(1) NOT NULL DEFAULT '0',
`products_discount_percentage` tinyint(1) NOT NULL DEFAULT '0',
`products_price_excluded` tinyint(1) NOT NULL DEFAULT '0',
`products_showhide` tinyint(1) NOT NULL DEFAULT '1',
`products_group` varchar(11) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_vendor_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_comments` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_customers_approved` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_id`),
KEY `idx_products_date_added` (`products_date_added`),
KEY `products_model` (`products_model`),
KEY `idx_products_customers_approved` (`products_customers_approved`),
KEY `idx_products_status` (`products_status`),
KEY `idx_products_price` (`products_price`),
KEY `products_thb_flag` (`products_thb_flag`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=97489 ;
CREATE TABLE IF NOT EXISTS `products_attributes` (
`products_attributes_id` int(11) NOT NULL AUTO_INCREMENT,
`products_id` int(11) NOT NULL DEFAULT '0',
`options_id` int(11) NOT NULL DEFAULT '0',
`options_values_id` int(11) NOT NULL DEFAULT '0',
`options_values_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`price_prefix` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_options_sort_order` smallint(3) unsigned NOT NULL DEFAULT '9999',
`product_attribute_is_free` tinyint(1) NOT NULL DEFAULT '0',
`products_attributes_weight` decimal(8,4) NOT NULL DEFAULT '0.0000',
`products_attributes_weight_prefix` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`attributes_price_onetime` decimal(15,4) NOT NULL DEFAULT '0.0000',
`attributes_display_only` tinyint(1) NOT NULL DEFAULT '0',
`attributes_default` tinyint(1) NOT NULL DEFAULT '0',
`attributes_qty_prices_onetime` mediumtext COLLATE utf8_unicode_ci,
`attributes_discounted` tinyint(1) NOT NULL DEFAULT '1',
`attributes_price_factor` decimal(8,2) NOT NULL DEFAULT '0.00',
`attributes_price_factor_offset` decimal(8,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`products_attributes_id`),
KEY `idx_products_attributes_products_id` (`products_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=57106 ;
CREATE TABLE IF NOT EXISTS `products_description` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`language_id` int(11) NOT NULL DEFAULT '1',
`products_name` varchar(160) COLLATE utf8_unicode_ci NOT NULL,
`products_blurb` mediumtext COLLATE utf8_unicode_ci,
`products_description` mediumtext COLLATE utf8_unicode_ci,
`products_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_viewed` int(5) DEFAULT '0',
`products_head_title_tag` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_head_desc_tag` longtext COLLATE utf8_unicode_ci,
`products_head_keywords_tag` longtext COLLATE utf8_unicode_ci,
`products_seo_url` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`products_id`,`language_id`),
KEY `products_name` (`products_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=97489 ;
CREATE TABLE IF NOT EXISTS `products_options_values` (
`products_options_values_id` int(11) NOT NULL DEFAULT '0',
`language_id` int(11) NOT NULL DEFAULT '1',
`products_options_values_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_options_values_sort_order` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_options_values_id`,`language_id`),
KEY `products_options_values` (`products_options_values_sort_order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `products_stock` (
`products_stock_id` int(11) NOT NULL AUTO_INCREMENT,
`products_id` int(11) NOT NULL DEFAULT '0',
`products_stock_attributes` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_stock_quantity` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_stock_id`),
UNIQUE KEY `idx_products_stock_attributes` (`products_id`,`products_stock_attributes`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=57375 ;
查看个人资料。在那里你可以看到引擎在哪里花费时间
示例
MariaDB [mysql]> set profiling=on;
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> select date('2010/01/01') + interval (seq * 30) Minute as mydate
from seq_0_to_10;
+---------------------+
| mydate |
+---------------------+
| 2010-01-01 00:00:00 |
| 2010-01-01 00:30:00 |
| 2010-01-01 01:00:00 |
| 2010-01-01 01:30:00 |
| 2010-01-01 02:00:00 |
| 2010-01-01 02:30:00 |
| 2010-01-01 03:00:00 |
| 2010-01-01 03:30:00 |
| 2010-01-01 04:00:00 |
| 2010-01-01 04:30:00 |
| 2010-01-01 05:00:00 |
+---------------------+
11 rows in set (0.00 sec)
MariaDB [mysql]> show profile all;
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+---------------+-------------+
| 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.000061 | 0.000054 | 0.000007 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NULL | NULL | NULL |
| checking permissions | 0.000006 | 0.000004 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | check_access | sql_parse.cc | 6051 |
| Opening tables | 0.000013 | 0.000012 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | open_tables | sql_base.cc | 4509 |
| After opening tables | 0.000003 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | open_tables | sql_base.cc | 4747 |
| System lock | 0.000002 | 0.000001 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 308 |
| Table lock | 0.000007 | 0.000006 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 313 |
| init | 0.000015 | 0.000014 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_select | sql_select.cc | 3427 |
| optimizing | 0.000006 | 0.000005 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1092 |
| statistics | 0.000010 | 0.000010 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1373 |
| preparing | 0.000013 | 0.000012 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1398 |
| executing | 0.000002 | 0.000001 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | exec_inner | sql_select.cc | 2551 |
| Sending data | 0.000022 | 0.000021 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | exec_inner | sql_select.cc | 3223 |
| end | 0.000003 | 0.000002 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_select | sql_select.cc | 3462 |
| query end | 0.000003 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_execute_command | sql_parse.cc | 5687 |
| closing tables | 0.000002 | 0.000001 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | close_thread_tables | sql_base.cc | 935 |
| Unlocking tables | 0.000005 | 0.000005 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_unlock_tables | lock.cc | 395 |
| freeing items | 0.000004 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_parse | sql_parse.cc | 7319 |
| updating status | 0.000012 | 0.000004 | 0.000007 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 1937 |
| cleaning up | 0.000002 | 0.000002 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 1956 |
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+---------------+-------------+
19 rows in set (0.00 sec)
MariaDB [mysql]>
我做了一些小测试。
那么第一个(慢速)数据库是否有可能是您在其中创建并使用插入和删除等操作的数据库。
然后看起来记录的顺序与副本的顺序不同。并且是否缺少索引 mariadb 必须读取更多时间的数据文件。
你可以轻松测试。
1) 关闭数据库服务器
2) 将表文件从旧位置复制到新位置,以便它们覆盖 "new" 一个
3) 启动DB-服务器并再次测试
hase 现在都测试相同的 "slow" 速度,您必须查看您的查询。缺少一个索引
显然您在 MySQL/MariaDB 引擎和/或优化器中发现了一个相当严重的错误。
MariaDB 工作人员 (Elena Stepanova) 已报告(向 Oracle 和 Maria)并复制(确认)此错误,他们已将其分配给他们的主要开发人员之一(Sergei Petrunia)。
我相信它可能很快就会修复,因为 MariaDB 的人似乎工作效率很高。
对于 Oracle,嗯,完全不同的故事...
如您发布的那样,您已经找到了临时解决方法,例如 运行 ALTER table FORCE
。干得好!
我遇到了 st运行ge 问题,在某些情况下查询速度慢:
我做了一些测试,并且能够将问题隔离到一个名为 products_description
的 table(所有 table 都是 MyISAM)。
起初我注意到当这个 table 是新的(即刚刚导入的)时,查询总是执行得很快(~0.3s)。
但是,如果我在任何时候(甚至在导入后立即)对此特定 table 执行任何这些操作:
CHECK
、OPTIMIZE
、ANALYZE
或 REPAIR
,查询突然减慢 x10 倍(大约需要 4.5 秒)并且一直保持缓慢。
请注意,我在 运行 查询时强制不缓存以确保结果正确。
只有当我对 table:
执行任何这些操作时,我才能恢复性能1) DROP
table 并再次导入。
或
2) ALTER
以下任何一项 table:Collation
或 CHECKSUM
或 DELAY_KEY_WRITE
。然后它以更改后的值快速运行,当恢复到旧值时,性能仍然很快。
或者可以执行 ALTER products_description FORCE
来恢复性能。
即便如此,如果我对 table 执行任何 CHECK
、OPTIMIZE
、ANALYZE
或 REPAIR
操作,查询速度也会下降直到我执行 1) 或 2)
我测试的另一件事:
在对 table 执行任何操作之前,我备份了 table 的文件(products_description.frm
、products_description.MYD
、products_description.MYI
)、运行查询,它运行快。然后我在table上执行CHECK
,运行查询,速度慢了10倍,我复制了备份文件并覆盖了3个文件,再次运行查询, 再次慢速.
我已经将数据库压缩到一个 ~5mb 的 zip 文件中(~80mb 解压缩)。 如果有人想在你自己的环境下测试数据库,请告诉我,我会发给你下载link。我可以在 MariaDB 10.1+ 和 MySQL 5.6+.
的几个不同服务器上重现它这是我 运行 的 SQL 查询,您应该使用以下方法进行测试:
SELECT DISTINCT pav.products_options_values_id,
pav.products_options_values_name,
pav.products_options_values_sort_order
FROM products_stock ps,
products_options_values pav,
(SELECT DISTINCT pa.products_id
FROM products_attributes pa,
products_options_values pov,
(SELECT p.products_id,
p.products_image,
p.products_subimage1,
pd.products_name,
p.products_quantity,
p.products_model,
p.products_ordered,
p.products_price,
p.products_date_added,
p.products_weight,
p.products_length,
p.products_width,
p.products_height,
p.products_tax_class_id,
p.products_status,
IF(s.status, s.specials_new_products_price, NULL)
AS
specials_new_products_price,
IF(s.status, s.specials_new_products_price,
p.products_price) AS
final_price,
IF(p.clearance_price < p.products_cost * 2.25,
p.clearance_price,
p.products_cost * 2.25)
AS
sorting_price
FROM products p
LEFT JOIN specials s
ON p.products_id = s.products_id
LEFT JOIN products_description pd
ON p.products_id = pd.products_id
WHERE
/*FASTIDS*/
p.products_status = '1'
AND Date_sub('2016-04-19', INTERVAL 7000 day) <=
p.products_date_added
) m
WHERE m.products_id = pa.products_id
AND pa.options_id = 1
AND pa.options_values_id = pov.products_options_values_id
AND pov.language_id = '1') q
WHERE q.products_id = ps.products_id
AND ps.products_stock_attributes =
Concat('1-', pav.products_options_values_id)
AND ps.products_stock_quantity > 0
ORDER BY pav.products_options_values_sort_order ASC
这是 EXPLAIN EXTENDED 结果。似乎优化器在两个 table 上的工作方式不同,但这并不能真正解释为什么会发生这种情况,因为复制的数据库应该是相同的。
这些是对慢速和快速数据库的查询分析的屏幕截图:
造成这种巨大差异的可能原因是什么?如何验证和解决这些问题?
编辑: 根据评论中的要求,这些是显示表:
CREATE TABLE IF NOT EXISTS `products` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`products_quantity` int(4) NOT NULL DEFAULT '0',
`products_model` bigint(20) DEFAULT NULL,
`products_image` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_med` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_lrg` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_sm_6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_image_xl_6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bimage` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage1` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage2` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage3` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage4` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage5` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_subimage6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_bsubimage6` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`clearance_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_cost` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_rmb_cost` decimal(7,2) DEFAULT NULL,
`products_best_rmb` decimal(7,2) DEFAULT NULL,
`products_thb_flag` tinyint(1) NOT NULL DEFAULT '0',
`products_date_added` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`products_last_modified` datetime DEFAULT NULL,
`products_date_available` datetime DEFAULT NULL,
`products_weight` decimal(5,2) NOT NULL DEFAULT '0.00',
`products_length` decimal(5,2) NOT NULL DEFAULT '0.00',
`products_width` decimal(5,2) DEFAULT '0.00',
`products_height` decimal(5,2) DEFAULT '0.00',
`products_status` tinyint(1) NOT NULL DEFAULT '0',
`products_tax_class_id` int(11) NOT NULL DEFAULT '0',
`manufacturers_id` int(11) DEFAULT NULL,
`products_ordered` int(11) NOT NULL DEFAULT '0',
`products_parent_id` int(11) NOT NULL DEFAULT '0',
`products_price1` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price2` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price3` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price4` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price5` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price6` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price7` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price8` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price9` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price10` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price11` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price1_qty` int(11) NOT NULL DEFAULT '0',
`products_price2_qty` int(11) NOT NULL DEFAULT '0',
`products_price3_qty` int(11) NOT NULL DEFAULT '0',
`products_price4_qty` int(11) NOT NULL DEFAULT '0',
`products_price5_qty` int(11) NOT NULL DEFAULT '0',
`products_price6_qty` int(11) NOT NULL DEFAULT '0',
`products_price7_qty` int(11) NOT NULL DEFAULT '0',
`products_price8_qty` int(11) NOT NULL DEFAULT '0',
`products_price9_qty` int(11) NOT NULL DEFAULT '0',
`products_price10_qty` int(11) NOT NULL DEFAULT '0',
`products_price11_qty` int(11) NOT NULL DEFAULT '0',
`products_qty_blocks` int(11) NOT NULL DEFAULT '1',
`products_group_access` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'G,0',
`products_nav_access` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'G,0',
`sort_order` smallint(3) NOT NULL DEFAULT '0',
`vendors_id` int(11) DEFAULT '1',
`vendors_product_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`vendors_prod_id` varchar(24) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`vendors_prod_comments` mediumtext COLLATE utf8_unicode_ci,
`products_qty_days` smallint(4) NOT NULL DEFAULT '0',
`products_qty_years` smallint(4) NOT NULL DEFAULT '0',
`products_quantity_order_min` int(8) NOT NULL DEFAULT '1',
`products_quantity_order_units` int(8) NOT NULL DEFAULT '1',
`products_price_list` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_price_rebate` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount1` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount2` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount3` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount4` decimal(15,4) NOT NULL DEFAULT '0.0000',
`products_discount1_qty` int(6) NOT NULL DEFAULT '0',
`products_discount2_qty` int(6) NOT NULL DEFAULT '0',
`products_discount3_qty` int(6) NOT NULL DEFAULT '0',
`products_discount4_qty` int(6) NOT NULL DEFAULT '0',
`products_discounts_id` int(11) NOT NULL DEFAULT '0',
`products_priced_by_attribute` tinyint(1) NOT NULL DEFAULT '0',
`product_is_free` tinyint(1) NOT NULL DEFAULT '0',
`product_is_call` tinyint(1) NOT NULL DEFAULT '0',
`products_quantity_mixed` tinyint(1) NOT NULL DEFAULT '0',
`product_is_showroom_only` tinyint(1) NOT NULL DEFAULT '0',
`products_discount_percentage` tinyint(1) NOT NULL DEFAULT '0',
`products_price_excluded` tinyint(1) NOT NULL DEFAULT '0',
`products_showhide` tinyint(1) NOT NULL DEFAULT '1',
`products_group` varchar(11) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_vendor_code` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_comments` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_customers_approved` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_id`),
KEY `idx_products_date_added` (`products_date_added`),
KEY `products_model` (`products_model`),
KEY `idx_products_customers_approved` (`products_customers_approved`),
KEY `idx_products_status` (`products_status`),
KEY `idx_products_price` (`products_price`),
KEY `products_thb_flag` (`products_thb_flag`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=97489 ;
CREATE TABLE IF NOT EXISTS `products_attributes` (
`products_attributes_id` int(11) NOT NULL AUTO_INCREMENT,
`products_id` int(11) NOT NULL DEFAULT '0',
`options_id` int(11) NOT NULL DEFAULT '0',
`options_values_id` int(11) NOT NULL DEFAULT '0',
`options_values_price` decimal(15,4) NOT NULL DEFAULT '0.0000',
`price_prefix` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_options_sort_order` smallint(3) unsigned NOT NULL DEFAULT '9999',
`product_attribute_is_free` tinyint(1) NOT NULL DEFAULT '0',
`products_attributes_weight` decimal(8,4) NOT NULL DEFAULT '0.0000',
`products_attributes_weight_prefix` char(1) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`attributes_price_onetime` decimal(15,4) NOT NULL DEFAULT '0.0000',
`attributes_display_only` tinyint(1) NOT NULL DEFAULT '0',
`attributes_default` tinyint(1) NOT NULL DEFAULT '0',
`attributes_qty_prices_onetime` mediumtext COLLATE utf8_unicode_ci,
`attributes_discounted` tinyint(1) NOT NULL DEFAULT '1',
`attributes_price_factor` decimal(8,2) NOT NULL DEFAULT '0.00',
`attributes_price_factor_offset` decimal(8,2) NOT NULL DEFAULT '0.00',
PRIMARY KEY (`products_attributes_id`),
KEY `idx_products_attributes_products_id` (`products_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=57106 ;
CREATE TABLE IF NOT EXISTS `products_description` (
`products_id` int(11) NOT NULL AUTO_INCREMENT,
`language_id` int(11) NOT NULL DEFAULT '1',
`products_name` varchar(160) COLLATE utf8_unicode_ci NOT NULL,
`products_blurb` mediumtext COLLATE utf8_unicode_ci,
`products_description` mediumtext COLLATE utf8_unicode_ci,
`products_url` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_viewed` int(5) DEFAULT '0',
`products_head_title_tag` varchar(80) COLLATE utf8_unicode_ci DEFAULT NULL,
`products_head_desc_tag` longtext COLLATE utf8_unicode_ci,
`products_head_keywords_tag` longtext COLLATE utf8_unicode_ci,
`products_seo_url` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`products_id`,`language_id`),
KEY `products_name` (`products_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=97489 ;
CREATE TABLE IF NOT EXISTS `products_options_values` (
`products_options_values_id` int(11) NOT NULL DEFAULT '0',
`language_id` int(11) NOT NULL DEFAULT '1',
`products_options_values_name` varchar(64) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_options_values_sort_order` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_options_values_id`,`language_id`),
KEY `products_options_values` (`products_options_values_sort_order`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE IF NOT EXISTS `products_stock` (
`products_stock_id` int(11) NOT NULL AUTO_INCREMENT,
`products_id` int(11) NOT NULL DEFAULT '0',
`products_stock_attributes` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`products_stock_quantity` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`products_stock_id`),
UNIQUE KEY `idx_products_stock_attributes` (`products_id`,`products_stock_attributes`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=57375 ;
查看个人资料。在那里你可以看到引擎在哪里花费时间
示例
MariaDB [mysql]> set profiling=on;
Query OK, 0 rows affected (0.00 sec)
MariaDB [mysql]> select date('2010/01/01') + interval (seq * 30) Minute as mydate
from seq_0_to_10;
+---------------------+
| mydate |
+---------------------+
| 2010-01-01 00:00:00 |
| 2010-01-01 00:30:00 |
| 2010-01-01 01:00:00 |
| 2010-01-01 01:30:00 |
| 2010-01-01 02:00:00 |
| 2010-01-01 02:30:00 |
| 2010-01-01 03:00:00 |
| 2010-01-01 03:30:00 |
| 2010-01-01 04:00:00 |
| 2010-01-01 04:30:00 |
| 2010-01-01 05:00:00 |
+---------------------+
11 rows in set (0.00 sec)
MariaDB [mysql]> show profile all;
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+---------------+-------------+
| 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.000061 | 0.000054 | 0.000007 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | NULL | NULL | NULL |
| checking permissions | 0.000006 | 0.000004 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | check_access | sql_parse.cc | 6051 |
| Opening tables | 0.000013 | 0.000012 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | open_tables | sql_base.cc | 4509 |
| After opening tables | 0.000003 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | open_tables | sql_base.cc | 4747 |
| System lock | 0.000002 | 0.000001 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 308 |
| Table lock | 0.000007 | 0.000006 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_lock_tables | lock.cc | 313 |
| init | 0.000015 | 0.000014 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_select | sql_select.cc | 3427 |
| optimizing | 0.000006 | 0.000005 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1092 |
| statistics | 0.000010 | 0.000010 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1373 |
| preparing | 0.000013 | 0.000012 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | optimize_inner | sql_select.cc | 1398 |
| executing | 0.000002 | 0.000001 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | exec_inner | sql_select.cc | 2551 |
| Sending data | 0.000022 | 0.000021 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | exec_inner | sql_select.cc | 3223 |
| end | 0.000003 | 0.000002 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_select | sql_select.cc | 3462 |
| query end | 0.000003 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_execute_command | sql_parse.cc | 5687 |
| closing tables | 0.000002 | 0.000001 | 0.000000 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | close_thread_tables | sql_base.cc | 935 |
| Unlocking tables | 0.000005 | 0.000005 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_unlock_tables | lock.cc | 395 |
| freeing items | 0.000004 | 0.000003 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | mysql_parse | sql_parse.cc | 7319 |
| updating status | 0.000012 | 0.000004 | 0.000007 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 1937 |
| cleaning up | 0.000002 | 0.000002 | 0.000001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | dispatch_command | sql_parse.cc | 1956 |
+----------------------+----------+----------+------------+-------------------+---------------------+--------------+---------------+---------------+-------------------+-------------------+-------------------+-------+-----------------------+---------------+-------------+
19 rows in set (0.00 sec)
MariaDB [mysql]>
我做了一些小测试。 那么第一个(慢速)数据库是否有可能是您在其中创建并使用插入和删除等操作的数据库。 然后看起来记录的顺序与副本的顺序不同。并且是否缺少索引 mariadb 必须读取更多时间的数据文件。
你可以轻松测试。
1) 关闭数据库服务器
2) 将表文件从旧位置复制到新位置,以便它们覆盖 "new" 一个
3) 启动DB-服务器并再次测试
hase 现在都测试相同的 "slow" 速度,您必须查看您的查询。缺少一个索引
显然您在 MySQL/MariaDB 引擎和/或优化器中发现了一个相当严重的错误。
MariaDB 工作人员 (Elena Stepanova) 已报告(向 Oracle 和 Maria)并复制(确认)此错误,他们已将其分配给他们的主要开发人员之一(Sergei Petrunia)。 我相信它可能很快就会修复,因为 MariaDB 的人似乎工作效率很高。
对于 Oracle,嗯,完全不同的故事...
如您发布的那样,您已经找到了临时解决方法,例如 运行 ALTER table FORCE
。干得好!