【问题标题】:MySQL table - performance, count of indexesMySQL 表 - 性能、索引计数
【发布时间】:2017-04-09 01:57:57
【问题描述】:

我有这种结构的表:

CREATE TABLE `supplies` (
 `cycle_id` int(11) NOT NULL,
 `subject_id` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
 `market_id` int(11) NOT NULL,
 `price` int(11) NOT NULL,
 `currency_id` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
 `offered_order` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`subject_id`,`market_id`,`cycle_id`,`price`),
 KEY `fk_supplies_subjects` (`subject_id`),
 KEY `fk_supplies_markets` (`market_id`),
 KEY `fk_supplies_currencies` (`currency_id`),
 CONSTRAINT `fk_supplies_currencies` FOREIGN KEY (`currency_id`) REFERENCES `currencies` (`currency_id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_supplies_subjects` FOREIGN KEY (`subject_id`) REFERENCES `subjects` (`subject_id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_supplies_markets` FOREIGN KEY (`market_id`) REFERENCES `markets` (`market_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

表格有大约 20,000 行。我有性能问题。我正在记录需要很长时间的 SQL 查询,从日志中我可以看到:

  1. INSERTs 缓慢放入表中。

    INSERT INTO supplies VALUES (11, 'userName', 18, 30, 'pound', 20) ; 
    
  2. 表中DELETEs 慢

    DELETE FROM supplies WHERE cycle_id = 6 AND market_id = 18 AND subject_id =  'userName' ;
    

我可以改进什么?

我想,更改索引会有所帮助,因为 PRIMARY 键由 4 列组成(有些甚至是 varchars)。但是我应该如何更改索引?

谢谢大家。

【问题讨论】:

  • 为什么选择非整数 id?
  • @Strawberry - 我没有设计这个表,我的目标是优化它。我会将 ID 更改为整数。
  • PRIMARY KEY 中包含price 似乎并不“正确”;请解释一下。
  • @RickJames 在techrepublic.com/article/the-great-primary-key-debate中查看更多信息
  • @AndréLima - 如果您的观点是增加价格会带来独特性,那么好吧。但是 123 美元和 123 欧元是不一样的,那不是要加上 currency_id 吗?

标签: mysql performance optimization indexing query-optimization


【解决方案1】:

您应该创建一个只有一个字段的主键。这是基本的性能优化

CREATE TABLE `supplies` (
 `supplies_id` int(11) NOT NULL AUTO_INCREMENT,
 `cycle_id` int(11) NOT NULL,
 `subject_id` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
 `market_id` int(11) NOT NULL,
 `price` int(11) NOT NULL,
 `currency_id` varchar(45) COLLATE utf8_unicode_ci DEFAULT NULL,
 `offered_order` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`supplies_id`),
 INDEX `index` (`subject_id` ASC,`market_id` ASC,`cycle_id` ASC,`price` ASC))
 KEY `fk_supplies_subjects` (`subject_id`),
 KEY `fk_supplies_markets` (`market_id`),
 KEY `fk_supplies_currencies` (`currency_id`),
 CONSTRAINT `fk_supplies_currencies` FOREIGN KEY (`currency_id`) REFERENCES `currencies` (`currency_id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_supplies_subjects` FOREIGN KEY (`subject_id`) REFERENCES `subjects` (`subject_id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `fk_supplies_markets` FOREIGN KEY (`market_id`) REFERENCES `markets` (`market_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

另一个可能的改进是删除级联约束。检查它们是否真的有必要。

【讨论】:

  • 好吧,我相信这会加快 INSERTS,但 DELETES 呢?
  • 只有一个字段的主键将加快插入和删除速度。移除级联约束将加快删除和更新速度。
  • 请解释一下“单场PK更好”的理由。
  • @AndréLima - PK 中的列数不会影响 ins/del 性能;辅助键的数量确实 - 但还不足以担心。
  • 由于有 4 个辅助键,添加代理键实际上减少了所需的整体空间(与原始的 4 列 PK 相比)。它可能减慢SELECTsINSERTsDELETEs。但如果没有关于查询的更多信息,很难说有多少。
猜你喜欢
  • 2015-08-13
  • 1970-01-01
  • 2011-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多