【发布时间】:2018-04-03 13:38:14
【问题描述】:
我正在开发用php,laravel框架,mariadb编写的仓库控制系统。要获取有关每个产品的所有信息,我们使用产品“历史”表,该表记录了对特定产品采取的所有操作。该表开始快速扩展,现在我们有大约 1500 万行 innoDB 表开始运行缓慢,尤其是在运行函数时,它需要对销售、创建、丢弃的产品数量等进行全面分析,然后它需要所有 1500 万行在一个查询上.. 所以我开始寻找方法,如何使用这个大表进行管理,因为索引不再起作用。 我开始考虑按日期拆分/分区此表,也许是行动?所以也许有人有这方面的经验,可以和我分享一些建议吗?非常感谢您的帮助!
CREATE TABLE `history` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`barcode` varchar(100) DEFAULT NULL,
`bag` varchar(100) DEFAULT NULL,
`action` int(10) unsigned DEFAULT NULL,
`place` int(10) unsigned DEFAULT NULL,
`price` decimal(10,2) DEFAULT NULL,
`old_price` decimal(10,2) DEFAULT NULL,
`user` int(11) DEFAULT NULL,
`amount` int(10) DEFAULT NULL,
`rotation` int(10) unsigned DEFAULT NULL,
`discount` decimal(10,2) DEFAULT NULL,
`discount_type` tinyint(2) unsigned DEFAULT NULL,
`original` int(10) unsigned DEFAULT NULL,
`was_in_shop` int(10) unsigned DEFAULT NULL,
`cate` int(10) unsigned DEFAULT NULL COMMENT 'grupe',
`sub_cate` int(10) unsigned DEFAULT NULL,
`comment` varchar(255) DEFAULT NULL,
`helper` varchar(255) DEFAULT NULL,
`created_at` timestamp NULL DEFAULT NULL,
`updated_at` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` timestamp NULL DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `barcode` (`barcode`),
KEY `action` (`action`),
KEY `original` (`original`),
KEY `created_at` (`created_at`),
KEY `bag` (`bag`)
) ENGINE=InnoDB AUTO_INCREMENT=16274267 DEFAULT CHARSET=utf8
例如查询:
select cate,
SUM(amount) AS amount, SUM(IF(discount>0,(price*amount)-discount,
(price*amount))) AS sum, SUM(IF(discount>0,IF(discount_type=1,
(discount*price)/100,discount),0)
) AS discount from history
where (history.action = '4'
and history.created_at >= '2017-11-01 00:00:00'
and history.created_at <= '2017-11-23 23:59:59'
)
and LENGTH(barcode) > 7
and history.deleted_at is null
group by cate
此查询用于获取有关已售产品的金额、总和、折扣信息(操作 4),在此示例中它是 2017-11-01 和 2017-11-23 之间的信息,EXPLAIN 给了我这个:
id - 1
select_type - SIMPLE
table - history
type - ref
possible_keys - action,created_at
key - action
key_len - 5
ref - const
rows - 1444272
Extra - Using where; Using temporary; Using filesort
所以它需要 150 万行,其中包含从 2017-01-01 到现在的数据的表,所以 2 年后它将需要 300 万行等等......当我只需要获取 2017-11 产品销售信息时.我还有很多类似的查询。
【问题讨论】:
-
“索引不再起作用”是什么意思?
-
我已经有 5 个索引(附件图片右侧的表格)添加更多索引不再加快速度。
-
在您的慢查询中添加
EXPLAIN是否支持这一假设? -
截图在这里几乎没用。请使用
SHOW CREATE TABLE描述您的情况并显示所涉及的查询。 -
用附加信息更新了主要问题
标签: php mysql mariadb partitioning