优化mysql架构,需要建议

问题描述 投票:0回答:2

我被要求帮助检查表格并提高性能。 该表是一个包含 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)吗?

请给我一些建议

mysql
2个回答
2
投票

是的,你是对的..

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

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

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.运行程序 analysis(),它会建议您最好的数据类型

7.如果可能且仅在有用时创建全文索引以利用 myisam

8.检查你的查询缓存(将查询缓存限制设置为按需)并激活慢查询日志

9.使用该表检查(并根据需要重写)所有查询后

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

如果表上的访问次数较多,则最好转移到 innodb,因为 myisam 会实现表级锁定,因此某些查询不会记录在慢查询日志中(获取锁所需的初始时间不计入执行时间)在 MySQL 中)


1
投票
  1. 打开MySQL慢查询日志以查找最慢的查询。

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

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

  4. 减少过大的列的大小是一个好主意。

  5. 据我所知,目前使用 MyISAM 的唯一原因是在进行全文搜索时。您应该按照您的建议切换到 InnoDB。 (更改表

    calculate
    引擎= InnoDB;)

  6. 这是一个扁平化的表以避免连接吗?此表中是否必须有

    OfferteTekst
    列?即使将其提取到相关表中也可能有所帮助,但如果您最终只是加入它,则没有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.