我有这个查询返回我想要的内容。
SELECT DISTINCT c.cust_id
FROM tbCustomers AS c
JOIN tbOrders AS o
ON o.order_custid = c.cust_id
JOIN tbPayments AS p
ON p.pay_custid = c.cust_id
WHERE (
DATE(o.order_date) > DATE_ADD(NOW(), INTERVAL -14 DAY)
AND o.order_status = '3'
AND o.order_exported = '0'
)
OR (
DATE(p.pay_date) > DATE_ADD(NOW(), INTERVAL -14 DAY)
AND p.pay_exported = '0'
)
但是执行速度相对较慢,我想找到一种方法来加快速度。 谁能给我一些指示?
编辑:
按要求解析和创建
说明:
(删除了数据库名称)
CREATE(S):
CREATE TABLE IF NOT EXISTS `tbCustomers` (
`cust_id` int(11) NOT NULL,
`cust_roundid` int(11) DEFAULT NULL,
`cust_email` varchar(250) DEFAULT NULL,
`cust_pass` varchar(32) DEFAULT NULL,
`cust_firstname` varchar(50) NOT NULL,
`cust_surname` varchar(50) NOT NULL,
`cust_address1` varchar(50) NOT NULL,
`cust_address2` varchar(50) DEFAULT NULL,
`cust_town` varchar(50) DEFAULT NULL,
`cust_county` varchar(50) DEFAULT NULL,
`cust_postcode` varchar(10) NOT NULL,
`cust_phone` varchar(20) DEFAULT NULL,
`cust_evephone` varchar(20) DEFAULT NULL,
`cust_delpointid` int(11) DEFAULT NULL,
`cust_notes` text NOT NULL,
`cust_delnotes` text,
`cust_delorder` int(10) NOT NULL DEFAULT '0',
`cust_likes` text,
`cust_dislikes` text,
`cust_active` int(1) NOT NULL DEFAULT '1',
`cust_auth` int(1) NOT NULL,
`cust_newsletter` tinyint(4) NOT NULL DEFAULT '1',
`cust_rep` varchar(250) DEFAULT NULL,
`cust_join` datetime DEFAULT NULL,
`cust_howheard` varchar(25) DEFAULT NULL,
`cust_friendname` varchar(50) DEFAULT NULL,
`cust_friend1staddress` varchar(50) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=18694 ;
-- --------------------------------------------------------
--
-- Table structure for table `tbOrders`
--
CREATE TABLE IF NOT EXISTS `tbOrders` (
`order_id` int(11) NOT NULL,
`order_custid` int(11) NOT NULL,
`order_date` datetime NOT NULL,
`order_status` int(1) NOT NULL,
`order_exported` tinyint(1) NOT NULL DEFAULT '0',
`order_subid` int(11) DEFAULT NULL,
`discount_vouchers` longtext
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=310575 ;
-- --------------------------------------------------------
--
-- Table structure for table `tbPayments`
--
CREATE TABLE IF NOT EXISTS `tbPayments` (
`pay_id` int(11) NOT NULL,
`pay_custid` int(11) NOT NULL,
`pay_date` datetime NOT NULL,
`pay_value` float NOT NULL,
`pay_detail` varchar(200) NOT NULL,
`pay_stref` varchar(50) DEFAULT NULL,
`pay_nomcode` int(5) NOT NULL,
`pay_exported` tinyint(1) NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=128264 ;
--
-- Indexes for dumped tables
--
--
-- Indexes for table `tbCustomers`
--
ALTER TABLE `tbCustomers`
ADD PRIMARY KEY (`cust_id`), ADD KEY `cust_name` (`cust_firstname`,`cust_surname`), ADD KEY `cust_email` (`cust_email`), ADD KEY `cust_newsletter` (`cust_newsletter`);
--
-- Indexes for table `tbOrders`
--
ALTER TABLE `tbOrders`
ADD PRIMARY KEY (`order_id`), ADD KEY `order_custid` (`order_custid`), ADD KEY `order_date` (`order_date`), ADD KEY `order_status` (`order_status`), ADD KEY `order_exported` (`order_exported`), ADD KEY `order_subid` (`order_subid`);
--
-- Indexes for table `tbPayments`
--
ALTER TABLE `tbPayments`
ADD PRIMARY KEY (`pay_id`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `tbCustomers`
--
ALTER TABLE `tbCustomers`
MODIFY `cust_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=18694;
--
-- AUTO_INCREMENT for table `tbOrders`
--
ALTER TABLE `tbOrders`
MODIFY `order_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=310575;
--
-- AUTO_INCREMENT for table `tbPayments`
--
ALTER TABLE `tbPayments`
MODIFY `pay_id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=128264;
此外,在where子句中为错误的列名称道歉 - 现在修复
干杯!
答案 0 :(得分:0)
我假设在WHERE子句中pay_custid
应该替换为pay_date
。
将查询重写为:
SELECT DISTINCT c.cust_id
FROM tbCustomers AS c
JOIN tbOrders AS o
ON o.order_custid = c.cust_id
JOIN tbPayments AS p
ON p.pay_custid = c.cust_id
WHERE (
o.order_date > CURDATE() - INTERVAL 14 DAY
AND o.order_status = 3
AND o.order_exported = 0
)
OR (
p.pay_date > CURDATE() - INTERVAL 14 DAY)
AND p.pay_exported = 0
)
这允许优化器在order_date
和pay_date
上使用索引,如果它包含在DATE
函数中,则无法使用索引。
我会在两个日期字段中添加索引,但每个表上的一个聪明的复合索引可能更灵活。
更好的可能是:
SELECT DISTINCT c.cust_id
FROM tbCustomers AS c
LEFT JOIN tbOrders AS o
ON o.order_custid = c.cust_id
AND o.order_date > CURDATE() - INTERVAL 14 DAY
AND o.order_status = 3
AND o.order_exported = 0
LEFT JOIN tbPayments AS p
ON p.pay_custid = c.cust_id
AND p.pay_date > CURDATE() - INTERVAL 14 DAY)
AND p.pay_exported = 0
WHERE (o.order_cust_id IS NOT NULL OR p.pay_cust_id IS NOT NULL)