我有一个
的mysql数据库
-需要寄送给他人的包裹表(此处为16,000条记录),
account_no,服务上的索引
-价格表(500,000条记录)-价格取决于:交货地区,客户价格率和服务类型(例如第二天等),索引
面积,价格,服务
-邮政编码(或邮政编码)的第一部分表,其区域为(3000)
-客户帐户表,包含价格比率(1600),价格比率索引
该查询找到发送包裹所需的价格,并使用唯一ID更新该包裹的客户价格
16000个包裹记录的价格更新需要70秒才能发送每个包裹
UPDATE
tbl_parcel AS t20, (
SELECT
id, service, rate_group, area,
(
SELECT
rate
FROM
tbl_rates_all t4
WHERE
t4.service = t10.service
AND t4.area = t10.area
AND t4.rate_group = t10.rate_group
)
AS price
FROM
(
SELECT
id,
t1.service,
rate_group,
area
FROM
tbl_parcel t1
JOIN
tbl_account t2
ON t1.account_no = t2.account_no
JOIN
tbl_pr_postcode t3
ON LEFT(full_pcode, locate(' ', full_pcode) - 1) = t3.postcode
) t10
) AS src
SET
t20.customer_price = src.price
WHERE
t20.id = src.id
花费70秒处理16000个包裹记录
最终正是这部分影响了效率
从
tbl_rates_all t4
哪里
t4.service = t10.service
AND t4.area = t10.area
AND t4.rate_group = t10.rate_group
我可以为每个费率使用单独的费率表,因为这是原始设计,因此变量将称为tbl_rates001,可能只有3000条记录,而没有500,000条记录。在mysql中执行此操作的问题是,在运行中动态创建表名时,如果不使用准备好的语句就不可能,因此我认为这种方法不好。遗憾的是,您无法使用用户变量来保存价格汇率编号,然后将其添加到表格汇率名称中。
我对数据库和查询还很陌生,所以如果有什么让您尖叫的东西会有所帮助,那么谢谢您的投入
致谢
按要求添加架构
CREATE TABLE `tbl_x_rate_all` (
`id` bigint(20) NOT NULL,
`service` varchar(4) NOT NULL,
`chargetype` char(1) NOT NULL,
`area` smallint(6) NOT NULL,
`rate` float(7,2) NOT NULL,
`rate_group` smallint(6) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
ALTER TABLE `tbl_x_rate_all` ADD PRIMARY KEY (`id`), ADD KEY `rate_group` (`rate_group`), ADD KEY `area` (`area`), ADD KEY `service` (`service`),
ADD KEY `chargetype` (`chargetype`);
答案 0 :(得分:0)
@Rich-
什么都没有跳出来。通过构建一些临时表,在主查询之外处理SET
并使用一些OUTER APPLY
而不是嵌套查询,您可能能够获得一些改进。
如果您通常对mysql /数据库还比较陌生,则EXPLAIN
函数在优化中可能非常有用
答案 1 :(得分:0)
假设id
,rate_group
和area
来自t1
内部的t10
,那么您的查询速度较慢?以下版本的版本:
UPDATE
tbl_parcel AS t20
INNER JOIN (
SELECT
t1.id,
t4.rate as price
FROM tbl_parcel t1
JOIN tbl_account t2 ON t1.account_no = t2.account_no
JOIN tbl_pr_postcode t3 ON LEFT(full_pcode, locate(' ', full_pcode) - 1) = t3.postcode
LEFT JOIN tbl_rates_all t4 ON t1.service = t4.service AND t1.area = t4.area
AND t1.rate_group = t4.rate_group
) src ON t20.id = src.id
SET
t20.customer_price = src.price
WHERE
t20.id = src.id
我猜您可能会进一步丢失子查询,而子查询往往很麻烦:
UPDATE
tbl_parcel AS t20
INNER JOIN tbl_parcel t1 ON t20.id = t1.id
INNER JOIN tbl_account t2 ON t1.account_no = t2.account_no
INNER JOIN tbl_pr_postcode t3 ON LEFT(full_pcode, locate(' ', full_pcode) - 1) = t3.postcode
LEFT JOIN tbl_rates_all t4 ON t1.service = t4.service AND t1.area = t4.area
AND t1.rate_group = t4.rate_group
SET
t20.customer_price = t4.rate
WHERE
t20.id = t1.id
-- can also replace with
-- TRUE
-- or lose it altogether
;
如果您有理由相信联接是瓶颈,则可以尝试在t1
和t4
的联接上添加索引:
create index tbl_rates_all_service_area_rate_group_index
on tbl_rates_all (service, area, rate_group);
create index tbl_parcel_service_area_rate_group_index
on tbl_parcel (service, area, rate_group);