我有一个可行的mysql查询但我发现当我使用NOT IN添加一些条件时它很慢。在这里是否有任何建议可以用其他词代替“NOT IN”并仍然得到相同的结果?谢谢你的帮助!
我的查询:
SELECT
CustomerId
FROM
mktg_account ma
LEFT JOIN mktg_account_customer mac
on mac.AccountId = ma.AccountId
WHERE
IsPurge = 1
AND mac.CustomerId NOT IN (SELECT mac.CustomerId
FROM mktg_account ma
LEFT JOIN mktg_account_customer mac
ON mac.AccountId = ma.AccountId
where IsPurge =0)
AND mac.CustomerId NOT IN (SELECT CustomerId
FROM mktg_unit_booking
WHERE DeadlineDate > Now()
AND IsDeleted <> 1
AND IsApproved=1)
AND mac.CustomerId NOT IN (SELECT mr.CustomerId
FROM mktg_reservation mr
LEFT JOIN mktg_reservation_customer mrc
on mr.ReservationId = mrc.ReservationId
WHERE IsDeleted <> 1
AND IsApproved=1
AND DeadlineDate > Now())
AND mac.CustomerId NOT IN (SELECT CustomerId
FROM mktg_customer
WHERE IsDeleted = 1
OR IsApproved <> 1 )
AND IsDeleted <> 1
AND IsApproved = 1
GROUP BY
ma.TreeId, mac.CustomerId
相关表格
CREATE TABLE IF NOT EXISTS mktg_account (
AccountId int(10) unsigned NOT NULL AUTO_INCREMENT,
AccountNo varchar(30) NOT NULL DEFAULT '',
AccountStatus varchar(1) DEFAULT NULL,
TreeId int(10) unsigned NOT NULL DEFAULT '0',
SalesDate datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PurchasePrice double NOT NULL DEFAULT '0',
SalesPersonId int(10) unsigned DEFAULT NULL,
FinancialTypeId int(10) unsigned DEFAULT NULL,
BillingCustomerId int(10) unsigned DEFAULT NULL,
EventId int(11) NOT NULL DEFAULT '0',
CategoryId int(11) NOT NULL DEFAULT '0',
RealEstateAgentId int(11) NOT NULL DEFAULT '0',
BusinessSourceId int(10) unsigned DEFAULT NULL,
BusinessSourceOthers varchar(300) DEFAULT NULL,
SalesPromotionId int(10) unsigned DEFAULT NULL,
Remarks text,
AgentName varchar(100) NOT NULL DEFAULT '',
AgentCompany varchar(100) NOT NULL DEFAULT '',
AgentContact varchar(100) DEFAULT NULL,
AgentRemarks text,
CreatedDateTime datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
CreatedBy int(10) unsigned NOT NULL DEFAULT '0',
PurgedDateTime datetime DEFAULT NULL,
PurgedBy int(10) unsigned DEFAULT NULL,
PurgedIP varchar(20) DEFAULT NULL,
IsDeleted tinyint(3) unsigned NOT NULL DEFAULT '0',
IsApproved tinyint(3) unsigned NOT NULL DEFAULT '1',
IsPurge tinyint(3) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (AccountId)
)
CREATE TABLE IF NOT EXISTS `mktg_account_customer` (
`AccountId` int(10) unsigned NOT NULL DEFAULT '0',
`CustomerId` int(10) unsigned NOT NULL DEFAULT '0',
`IsNominee` varchar(1) NOT NULL DEFAULT 'N',
`SortIdx` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`AccountId`,`CustomerId`),
KEY `FK_mktg_agreement_customer_1` (`CustomerId`),
KEY `AccountId` (`AccountId`)
)
CREATE TABLE IF NOT EXISTS `mktg_unit_booking` (
`BookingId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`UnitId` int(10) unsigned NOT NULL DEFAULT '0',
`ProjectLevelId` int(10) unsigned NOT NULL DEFAULT '0',
`ProductType` varchar(20) NOT NULL DEFAULT '',
`SalesPersonId` int(10) unsigned DEFAULT NULL,
`ReserveDate` datetime DEFAULT NULL,
`DeadlineDate` datetime DEFAULT NULL,
`CustomerId` int(10) unsigned NOT NULL DEFAULT '0',
`Remark` varchar(250) DEFAULT NULL,
`CreatedDateTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`CreatedBy` int(10) unsigned NOT NULL DEFAULT '0',
`CreatedIP` varchar(20) NOT NULL DEFAULT '',
`IsDeleted` tinyint(3) unsigned NOT NULL DEFAULT '0',
`IsApproved` tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`BookingId`),
KEY `UnitId` (`UnitId`),
KEY `IsDeleted` (`IsDeleted`),
KEY `IsApproved` (`IsApproved`),
KEY `CustomerId` (`CustomerId`),
KEY `DeadlineDate` (`DeadlineDate`)
)
CREATE TABLE IF NOT EXISTS `mktg_reservation` (
`ReservationId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ProjectLevelId` int(10) unsigned NOT NULL DEFAULT '0',
`SalesPersonId` int(10) unsigned NOT NULL DEFAULT '0',
`ReserveDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`DeadlineDate` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`CustomerId` int(10) unsigned NOT NULL DEFAULT '0',
`Remark` varchar(500) NOT NULL DEFAULT '',
`SolicitorId` int(10) unsigned DEFAULT NULL,
`CreatedDateTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`CreatedBy` int(10) unsigned NOT NULL DEFAULT '0',
`CreatedIP` varchar(20) NOT NULL DEFAULT '',
`IsDeleted` tinyint(3) unsigned NOT NULL DEFAULT '0',
`IsApproved` tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`ReservationId`),
KEY `CustomerId` (`CustomerId`)
)
CREATE TABLE IF NOT EXISTS `mktg_reservation_customer` (
`ReservationCustomerId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`ReservationId` int(10) unsigned NOT NULL DEFAULT '0',
`CustomerId` int(10) unsigned NOT NULL DEFAULT '0',
`IsNominee` varchar(1) NOT NULL DEFAULT 'N',
PRIMARY KEY (`ReservationCustomerId`),
KEY `ReservationId` (`ReservationId`),
KEY `CustomerId` (`CustomerId`)
)
CREATE TABLE IF NOT EXISTS `mktg_customer` (
`CustomerId` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CustomerCode` varchar(20) NOT NULL DEFAULT '',
`CustomerSeriesNo` varchar(20) NOT NULL DEFAULT '',
`CustomerFirstName` varchar(45) DEFAULT NULL,
`CustomerSurname` varchar(45) DEFAULT NULL,
`ChristianName` varchar(45) DEFAULT NULL,
`CustomerName` varchar(100) NOT NULL DEFAULT '',
`BusinessSourceId` int(10) unsigned DEFAULT NULL,
`ContactMode` varchar(45) DEFAULT NULL,
`MobilePhone` varchar(45) DEFAULT NULL,
`Email` varchar(300) DEFAULT NULL,
`ICNo` varchar(20) DEFAULT NULL,
`Salutation` varchar(50) NOT NULL DEFAULT '',
`DateOfBirth` datetime DEFAULT NULL,
`Gender` varchar(2) NOT NULL DEFAULT '',
`Occupation` varchar(100) DEFAULT NULL,
`CorrespondenceTypeId` int(10) unsigned DEFAULT NULL,
`FinanceSourceId` int(10) unsigned DEFAULT NULL,
`CustomerGroupId` int(11) DEFAULT NULL,
`CustomerCategoryId` int(10) unsigned DEFAULT NULL,
`MailingAddress` varchar(200) NOT NULL DEFAULT '',
`MailingPostCode` varchar(10) DEFAULT NULL,
`MailingState` varchar(100) DEFAULT NULL,
`MailingCountry` varchar(100) DEFAULT NULL,
`ReceiveMail` varchar(1) DEFAULT NULL,
`CreatedDateTime` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`CreatedBy` int(10) unsigned NOT NULL DEFAULT '0',
`CreatedIP` varchar(20) NOT NULL DEFAULT '',
`IsDeleted` tinyint(3) unsigned NOT NULL DEFAULT '0',
`IsApproved` tinyint(3) unsigned NOT NULL DEFAULT '1',
PRIMARY KEY (`CustomerId`)
)
更新的查询:
SELECT CustomerId FROM mktg_account ma
left join mktg_account_customer mac on mac.AccountId = ma.AccountId
where IsPurge =1 and not exists (SELECT mac.CustomerId FROM mktg_account ma
left join mktg_account_customer mac on mac.AccountId = ma.AccountId
where IsPurge =0)
and not exists (SELECT CustomerId FROM mktg_unit_booking where DeadlineDate > Now() and IsDeleted <> 1 and IsApproved=1)
and not exists (SELECT mr.CustomerId FROM mktg_reservation mr
left join mktg_reservation_customer mrc on mr.ReservationId = mrc.ReservationId where IsDeleted <> 1
and IsApproved=1 and DeadlineDate > Now())
and not exists (SELECT CustomerId FROM mktg_customer where IsDeleted = 1 or IsApproved <> 1 )
and IsDeleted <> 1 and IsApproved = 1
GROUP BY ma.TreeId ,mac.CustomerId
答案 0 :(得分:0)
或许可以重新考虑一下您的查询。看到你在mktg_account表上将AccountID作为PRIMARY KEY应该没有重复的accountids,使初始子查询毫无意义:
SELECT CustomerId FROM mktg_account ma
left join mktg_account_customer mac on mac.AccountId = ma.AccountId
where IsPurge =1
您只需要查询。
这似乎也毫无意义:
and mac.CustomerId not in (SELECT CustomerId FROM mktg_customer where IsDeleted = 1 or IsApproved <> 1 )
正如你的下一行做同样的事情,虽然来自另一张桌子。
如果没有看到数据,我会尝试用连接替换所需的子查询
答案 1 :(得分:0)
有两种方法可以改进查询;我不知道哪个更好。两者都替换x NOT IN ( SELECT ... )
计划A:
NOT EXISTS ( SELECT * ... )
B计划:
LEFT JOIN ... WHERE .. IS NULL
关于其他主题......
mktg_account_customer
中,KEY AccountId
(AccountId
)是多余的,可以删除。否则,表格设计得很好(假设ENGINE=InnoDB
)IsApproved
(IsApproved
))很少有用。以标志开头的复合索引可能很有用。JOINing
时,请使用别名。示例:来自where IsPurge =0
的哪个表格不明显。LEFT
的作用相同时,请勿说JOIN
。 LEFT
表示“右”表可能包含您想要的NULLs
行。我非常确定where IsPurge =0
的行为相同 - 如果行丢失,IsPurge
将NULL
,因此不会0
。 编辑:也许这会采用EXISTS
方法:
SELECT CustomerId
FROM mktg_account ma
left join mktg_account_customer mac ON mac.AccountId = ma.AccountId
where ma.IsPurge =1
and ma.IsDeleted <> 1
and ma.IsApproved = 1
and not exists
( SELECT *
FROM mktg_account ma2
left join mktg_account_customer mac2 ON mac2.AccountId = ma2.AccountId
where IsPurge =0
AND mac.CustomerId = mac2.CustomerId
)
and not exists
( SELECT *
FROM mktg_unit_booking
where DeadlineDate > Now()
and IsDeleted <> 1
and IsApproved=1
AND CustomerId = mac.CustomerId
)
and not exists
( SELECT *
FROM mktg_reservation mr
left join mktg_reservation_customer mrc
ON mr.ReservationId = mrc.ReservationId
where IsDeleted <> 1
and IsApproved=1
and DeadlineDate > Now()
AND mr.CustomerId= mac.CustomerId
)
and not exists
( SELECT *
FROM mktg_customer
where ( IsDeleted = 1 or IsApproved <> 1 )
AND CustomerId = mac.CustomerId
)
GROUP BY ma.TreeId, mac.CustomerId