优化mysql架构,需要建议

时间:2013-01-18 10:21:06

标签: mysql

我被要求帮助检查一张桌子并提高性能。 该表是一个大表,行数为2.000.000,并且正在快速增长。 有很多用户正在使用此表,其中包含大量更新/插入和删除查询。

也许你可以给我一些提高性能和可靠性的好建议

以下是表格定义:

CREATE TABLE `calculate` (
  `GROUP_LINE_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `GROUP_LINE_PARENT_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `MOEDER_LINE_CODE` BIGINT(250) NOT NULL DEFAULT '0',
  `CALC_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `GROUP_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `CODE` VARCHAR(250) DEFAULT NULL,
  `DESCRIPTION` VARCHAR(250) DEFAULT NULL,
  `RAW_AMOUNT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `AMOUNT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `UNIT` VARCHAR(100) DEFAULT NULL,
  `MEN_HOURS` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `PRICE_PER_UNIT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `CONTRACTOR_UNIT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `POSTS_PER_UNIT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `SORT_INDEX` BIGINT(250) NOT NULL DEFAULT '0',
  `FACTOR` DECIMAL(50,4) NOT NULL DEFAULT '0.0000',
  `FACTOR_TYPE` INT(2) NOT NULL DEFAULT '0',
  `ROUND_AT` DECIMAL(50,2) NOT NULL DEFAULT '0.00',
  `MATERIAL_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `MINIMUM` DECIMAL(50,2) NOT NULL DEFAULT '0.00',
  `LINE_TYPE` INT(1) NOT NULL DEFAULT '0',
  `ONDERDRUKT` INT(5) NOT NULL DEFAULT '0',
  `MARKED` INT(5) NOT NULL DEFAULT '0',
  `IS_TEXT` INT(5) NOT NULL DEFAULT '0',
  `BRUTO_PRICE` DECIMAL(20,2) NOT NULL DEFAULT '0.00',
  `AMOUNT_DISCOUNT` DECIMAL(20,3) NOT NULL DEFAULT '0.000',
  `FROM_CONSTRUCTOR` INT(5) NOT NULL DEFAULT '0',
  `CHANGE_DATE` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
  `BEREKENING_VALUE` INT(5) NOT NULL DEFAULT '0',
  `MAATVOERING_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `KOZIJN_CALC_ID` BIGINT(250) NOT NULL DEFAULT '0',
  `IS_KOZIJN_CALC_TOTALS` INT(5) NOT NULL DEFAULT '0',
  `EAN_CODE` VARCHAR(150) DEFAULT NULL,
  `UURLOON_ID` BIGINT(20) NOT NULL DEFAULT '0',
  `ORG_PRICE_PER_UNIT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `ORG_CONTRACTOR_UNIT` DECIMAL(50,3) NOT NULL DEFAULT '0.000',
  `BTWCode` INT(5) NOT NULL DEFAULT '0',
  `IS_CONTROLE_GETAL` INT(5) NOT NULL DEFAULT '0',
  `AttentieRegel` INT(5) NOT NULL DEFAULT '0',
  `KozijnSelectionRowId` BIGINT(250) NOT NULL DEFAULT '0',
  `OfferteTekst` TEXT,
  `VerliesFactor` DECIMAL(15,4) NOT NULL DEFAULT '0.0000',
  PRIMARY KEY (`GROUP_LINE_ID`),
  KEY `GROUP_LINE_PARENT_ID` (`GROUP_LINE_PARENT_ID`),
  KEY `MOEDER_LINE_CODE` (`MOEDER_LINE_CODE`),
  KEY `CALC_ID` (`CALC_ID`),
  KEY `GROUP_ID` (`GROUP_ID`),
  KEY `MATERIAL_ID` (`MATERIAL_ID`),
  KEY `MAATVOERING_ID` (`MAATVOERING_ID`),
  KEY `KOZIJN_CALC_ID` (`KOZIJN_CALC_ID`),
  KEY `IS_KOZIJN_CALC_TOTALS` (`IS_KOZIJN_CALC_TOTALS`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

在我看来

  • 将表引擎更改为InnoDB
  • bigint(250)可以改为bigint(10)的int(10)吗?

请给我一些建议

2 个答案:

答案 0 :(得分:2)

是的,你是对的..

1.记住表中的主键是在每个其他键的最后一个分配的 所以保持你的主键尽量减小我认为int足够它可以处理多达20亿条记录并且不需要大的int

2.更改key_buffer_size(最多25%的内存)如果您的服务器有许多Myisam或只有myisam表,您可以将其增加到60-70% 尝试手动chache

SET GLOBAL keycache1.key_buffer_size=256*1024;
CACHE INDEX t1,t2 IN keycache1;
LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;

(IGNORE LEAVES修饰符仅导致重新加载索引的非叶节点的块)

3.正如您所提到的,您的表越来越快,最好对表进行分区,以提高性能

4.执行表维护任务,例如经常分析表,这将更新索引,优化表并检查它并在有任何错误时进行修复(经常优化表因为你说的有很多删除)

5.如果您不想更改引擎,请启用delay_key_write变量(特定于myisam),这样可以在关闭表后更新密钥

6.运行程序analyze(),它建议您使用最佳数据类型

7.创建全文索引,尽可能采取myisam的优点,并且只有在有用的情况下

8.检查您的查询缓存(根据需要设置查询缓存限制)并使慢查询日志生效

9.一次使用表

检查(并在需要时重写)所有查询

最后如果你想改变引擎 将您的表存储引擎更改为innodb并增加innodb_buffer_pool_size它可能对您有所帮助

如果表上的访问次数越多越好转移到innodb,因为myisam将实现表级锁定,因为一些查询没有记录在慢查询日志中(获取锁所需的初始时间不在MySQL中的执行时间)

答案 1 :(得分:1)

  1. 启用MySQL Slow Query Log以查找最慢的查询。

  2. 如果选择它们,则通过EXPLAIN运行它们以找出正在使用的索引(如果有)。您可以将一些索引转换为多列索引,并以这种方式找到一些改进。有关差异的详细讨论,请参阅Multiple Indexes vs Multi-Column Indexes

  3. 由于您的索引,插入,更新和删除可能会变慢。您需要确定哪些索引未被使用并删除它们。不幸的是,除了运行最热门的查询之外,没有一种简单的方法可以做到这一点。

  4. 减小超大列的大小是个好主意。

  5. 我知道这些天使用MyISAM的唯一原因是进行全文搜索。你应该按照你的建议切换到InnoDB。 (ALTER TABLE calculate ENGINE = InnoDB;)

  6. 这是一个扁平的表,以避免连接?您是否必须在此表中包含OfferteTekst列?即使将其提取到相关的表格中也可能会有所帮助,但如果您最终只是加入其中,则可能会有所帮助。