我使用這個查詢來獲得聚合子查詢的結果,但性能非常糟糕,雖然行只有 92行,但它需要大約12 秒,tborders 表有大約 37000 行,但它認為這段時間要花很多時間
您能建議對此查詢進行一些改進嗎?
select id, group_name,merchant_id,
(select count(id) from tborders where tborders.group_id = og.id) as ords_count,
(select SUM(order_price) from tborders where tborders.group_id = og.id) as total_order_price,
(select SUM(delivery_price) from tborders where tborders.group_id = og.id) as total_delivery_price
from tborders_groups og
這也是該表的架構
CREATE TABLE `tborders_groups` (
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`merchant_id` int(11) DEFAULT NULL,
`group_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='orders groubs';
--
-- Dumping data for table `tborders_groups`
--
--
-- Indexes for table `tborders_groups`
--
ALTER TABLE `tborders_groups`
ADD PRIMARY KEY (`id`),
ADD KEY `id` (`id`),
ADD KEY `merchant_id` (`merchant_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tborders_groups`
--
ALTER TABLE `tborders_groups`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=95;
COMMIT;
這是 tborders 的架構
CREATE TABLE `tborders` (
`id` int(11) NOT NULL,
`device_type` varchar(255) DEFAULT 'android',
`order_code` int(20) NOT NULL,
`order_status` tinyint(1) NOT NULL DEFAULT 1,
`merchant_id` int(11) NOT NULL,
`driver_id` int(11) DEFAULT NULL,
`client_id` int(11) DEFAULT 0,
`from_lng` decimal(9,6) DEFAULT NULL,
`to_lat` decimal(8,6) DEFAULT NULL,
`to_lng` decimal(9,6) DEFAULT NULL,
`distance` int(11) DEFAULT NULL,
`speed` int(11) DEFAULT NULL,
`orders_count` tinyint(1) NOT NULL DEFAULT 0,
`order_address` varchar(500) CHARACTER SET utf8 NOT NULL,
`canceled_at` time DEFAULT NULL,
`taken_at` time DEFAULT NULL,
`canceled_by` enum('merchant','driver') DEFAULT NULL,
`accepted_at` time DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
`updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`from_lat` decimal(8,6) DEFAULT NULL,
`order_price` int(11) NOT NULL DEFAULT 0,
`order_type` tinyint(1) NOT NULL DEFAULT 2,
`group_id` int(10) UNSIGNED NOT NULL,
`client_address` varchar(100) CHARACTER SET utf8 NOT NULL,
`delivery_price` int(10) UNSIGNED NOT NULL,
`notes` varchar(100) CHARACTER SET utf8 NOT NULL,
`has_paid` tinyint(1) NOT NULL DEFAULT 0,
`finished_at` timestamp NULL DEFAULT NULL,
`finished_attt` timestamp NULL DEFAULT current_timestamp(),
`area_id` tinyint(4) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Dumping data for table `tborders`
--
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tborders`
--
ALTER TABLE `tborders`
ADD PRIMARY KEY (`id`),
ADD KEY `id` (`id`),
ADD KEY `order_status` (`order_status`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tborders`
--
ALTER TABLE `tborders`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=37169;
COMMIT;
uj5u.com熱心網友回復:
您應該為此查詢使用 join & group by:
select og.id, og.group_name,og.merchant_id, count(tb.id) as ords_count,
sum(tb.order_price) as total_order_price, sum(tb.delivery_price) as total_delivery_price
from tborders_groups og
join tborders tb on tb.group_id=og.id
group by og.id, og.group_name,og.merchant_id
無論如何,查詢的時間并不(僅)取決于答案的行數。這取決于處理查詢以分析所有資料集以獲取這些行的時間。
對于您的索引,這應該是您的 tborders 索引:
ALTER TABLE `tborders`
ADD PRIMARY KEY (`id`),
ADD KEY `group_id` (`group_id`),
ADD KEY `order_status` (`order_status`);
將 id 同時作為主鍵和鍵是沒有意義的,因為主鍵是唯一的鍵。
所以對于 tborders_groups 他們應該是:
ALTER TABLE `tborders_groups`
ADD PRIMARY KEY (`id`),
ADD KEY `merchant_id` (`merchant_id`);
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/477661.html
下一篇:SQL獲取不在JOIN中的行
