CRM 表示例:
`crm` example:
+----+--------+---------------------+--------------------+
| id | name | date | status |
+----+--------+---------------------+--------------------+
| 1 | john | 2017-12-27 10:58:10 | A status |
| 2 | steve | 2017-12-27 10:58:08 | A status |
| 3 | eric | 2017-12-27 10:58:04 | Delivery Arranged |
| 4 | phil | 2017-12-27 10:57:55 | A status |
| 5 | bob | 2017-12-27 10:57:52 | A status |
| 6 | foo | 2017-12-27 10:57:50 | A status |
| 7 | steven | 2017-12-27 10:57:48 | Delivery Arranged |
| 8 | paul | 2017-12-27 10:57:43 | A status |
| 9 | alex | 2017-12-27 10:57:31 | Delivery Arranged |
我的查询对象是返回crm
交付安排的status
行数,date
介于{{1}之间}和2017-12-01
。
所以,这是我的主要查询:
2018-01-01
结果:
SET @from='2017-12-01';
SET @to='2018-01-01';
SELECT
COUNT(*) AS `delivery_arranged`
FROM
`crm` a
WHERE
a.`status` = 'Delivery Arranged'
AND DATE(a.`date`) BETWEEN @from AND @to
一切都好。但是我希望打折那些之前曾经(实际上除此日期范围之外)的行已设置为交付安排。我有一个 statuslog 表,我可以用它:
STATUSLOG 表示例:
+---------------------+
| delivery_arranged |
+---------------------+
| 30 |
因此,使用此表格,我可以从`statuslog` example:
+--------+-------+---------------------+-----------+---------------------+
| id | crmid | date | user | status |
+--------+-------+---------------------+-----------+---------------------+
| 818572 | 1 | 2017-12-27 10:58:10 | johnsmith | Some status change |
| 818571 | 2 | 2017-12-27 10:58:08 | johnsmith | Some status change |
| 818570 | 3 | 2017-12-27 10:58:04 | another | Delivery Arranged |
| 818569 | 4 | 2017-12-27 10:57:55 | another | Delivery Arranged |
| 818568 | 5 | 2017-12-27 10:57:52 | johnsmith | Some status change |
| 818567 | 6 | 2017-12-27 10:57:50 | another | Some status change |
| 818566 | 7 | 2017-12-27 10:57:48 | johnsmith | Delivery Arranged |
| 818565 | 8 | 2017-12-27 10:57:43 | another | Some status change |
| 818564 | 9 | 2017-12-27 10:57:31 | johnsmith | Some status change |
获取不在日期范围之间的行,然后执行statuslog
:
NOT IN
这可行,但根据日期范围的大小,它可能需要很长时间! SELECT
COUNT(*) AS `delivery_arranged`
FROM
`crm` a
WHERE
a.`status` = 'Delivery Arranged'
AND DATE(a.`date`) BETWEEN @from AND @to
AND a.`id`
NOT IN (
SELECT
a.crmid AS `crmid`
FROM
statuslog a
WHERE
a.status = 'Delivery Arranged'
AND DATE(a.`date`) NOT BETWEEN @from AND @to
GROUP BY a.crmid
ORDER BY a.`date` DESC
)
有> 2,000,000行。
如何更快地进行此查询?
答案 0 :(得分:0)
如果您使用cli packages: (C:\Users\Houssem\AppData\Roaming\npm\node_modules)
@ionic/cli-utils : 1.19.0
ionic (Ionic CLI) : 3.19.0
global packages:
cordova (Cordova CLI) : 7.1.0
local packages:
@ionic/app-scripts : 3.1.4
Cordova Platforms : android 6.3.0
Ionic Framework : ionic-angular 3.9.2
System:
Android SDK Tools : 26.1.1
Node : v8.9.3
npm : 5.5.1
OS : Windows 10
Environment Variables:
ANDROID_HOME : C:\Users\Houssem\AppData\Local\Android\sdk
Misc:
backend : pro
/ LEFT JOIN
:
WHERE
对于此版本,您需要SELECT COUNT(*) AS delivery_arranged
FROM crm c LEFT JOIN
statuslog sl
ON sl.crmid = c.id AND
sl.status = 'Delivery Arranged'
sl.date >= @from AND
sl.date < @to + INTERVAL 1 DAY
WHERE c.status = 'Delivery Arranged' AND
c.date >= @from AND
c.date < @to + INTERVAL 1 DAY AND
sl.crmid IS NULL;
和crm(status, date, id)
上的索引。
请注意,这会更改日期比较以避免对列进行函数调用。这使得使用包含statuslog(crmid, status, date)
列的索引更为可行。
答案 1 :(得分:0)
左连接可能比代理子查询更好:
date
另外,请记住使用正确的索引。