我被要求帮助检查一张桌子并提高性能。 该表是一个大表,行数为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;
在我看来
请给我一些建议
答案 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)
启用MySQL Slow Query Log以查找最慢的查询。
如果选择它们,则通过EXPLAIN运行它们以找出正在使用的索引(如果有)。您可以将一些索引转换为多列索引,并以这种方式找到一些改进。有关差异的详细讨论,请参阅Multiple Indexes vs Multi-Column Indexes。
由于您的索引,插入,更新和删除可能会变慢。您需要确定哪些索引未被使用并删除它们。不幸的是,除了运行最热门的查询之外,没有一种简单的方法可以做到这一点。
减小超大列的大小是个好主意。
我知道这些天使用MyISAM的唯一原因是进行全文搜索。你应该按照你的建议切换到InnoDB。 (ALTER TABLE calculate
ENGINE = InnoDB;)
这是一个扁平的表,以避免连接?您是否必须在此表中包含OfferteTekst
列?即使将其提取到相关的表格中也可能会有所帮助,但如果您最终只是加入其中,则可能会有所帮助。