where substr(lot_id,1,2) not in('CA','CW','ES','E0','EM') and lot_type = 'Production' AND LOT_ID NOT LIKE 'H%' and substr(lot_id,7,4)='.00F' and ope_category in ('Ship','Unship')请优化下
时间: 2023-12-21 07:04:35 浏览: 33
该 SQL 语句可以优化如下:
1. 将 WHERE 子句中的函数调用改为使用列范围,例如:
```
WHERE lot_id >= 'F1000000.00F' AND lot_id < 'Z9999999.00G'
```
2. 创建索引以覆盖 WHERE 子句中的所有列,例如:
```
CREATE INDEX idx_lot_id ON table_name (lot_id);
CREATE INDEX idx_lot_type ON table_name (lot_type);
CREATE INDEX idx_ope_category ON table_name (ope_category);
```
3. 如果表比较大,可以考虑将这个表分区,例如按照 lot_type 进行分区,这样可以进一步提高查询性能。
4. 如果查询经常使用,则可以将结果缓存起来,以避免每次查询都进行全表扫描。
综上所述,这些优化措施可以显著提高 SQL 查询的性能。
相关问题
select lot_id, max(claim_time)claim_time, count(case when(ope_category='Ship')then lot_id else null end) as LS, count(case when(ope_category='Unship') then lot_id else null end) as LUS from f3rpt.F3_TB_DAILY_FABOUT where substr(lot_id,1,2) not in('CA','CW','ES','E0','EM') and lot_type = 'Production' AND LOT_ID NOT LIKE 'H%' and substr(lot_id,7,4)='.00F' and ope_category in ('Ship','Unship') and year(claim_time) = year(current date - 1 days) and month(claim_time) = month(current date - 1 days) group by lot_id) as a where LS - LUS > 0 ,以上sql如何优化
这个SQL语句中,可以优化的地方如下:
1. 在WHERE子句中,使用函数year()和month()可能导致索引失效,可以考虑将其改为claim_time的范围查询,如下所示:
```
AND claim_time >= DATE(current date - 1 month) AND claim_time < DATE(current date)
```
2. 在COUNT函数中,使用CASE语句进行条件统计,可以改为使用SUM函数,如下所示:
```
SUM(CASE WHEN ope_category='Ship' THEN 1 ELSE 0 END) AS LS
SUM(CASE WHEN ope_category='Unship' THEN 1 ELSE 0 END) AS LUS
```
3. 在WHERE子句中,使用了聚合函数,将查询结果限制在LS-LUS>0的记录,这种方式不利于索引的使用,可以考虑使用HAVING子句,如下所示:
```
HAVING LS > LUS
```
4. 在子查询中,只需要查询claim_time的最大值,可以使用MAX函数来代替ORDER BY和LIMIT 1子句,如下所示:
```
MAX(claim_time) AS claim_time
```
综上所述,优化后的SQL语句如下:
```
SELECT lot_id, MAX(claim_time) AS claim_time,
SUM(CASE WHEN ope_category='Ship' THEN 1 ELSE 0 END) AS LS,
SUM(CASE WHEN ope_category='Unship' THEN 1 ELSE 0 END) AS LUS
FROM f3rpt.F3_TB_DAILY_FABOUT
WHERE substr(lot_id,1,2) NOT IN ('CA','CW','ES','E0','EM')
AND lot_type = 'Production'
AND LOT_ID NOT LIKE 'H%'
AND substr(lot_id,7,4)='.00F'
AND ope_category IN ('Ship','Unship')
AND claim_time >= DATE(current date - 1 month) AND claim_time < DATE(current date)
GROUP BY lot_id
HAVING LS > LUS;
```
SELECT lot_id, max(claim_time) claim_time, count( case when (open_category= 'Ship') then lot_id else null end ) as LS, COUNT( case when (ope_category = "Unship") then lot_id else null end ) as LUS FROM f3rpt.F3_TB_DAILY_FABOUT WHERE SUBSTR(lot_id,1,2) not in ('CA','CW','ES','EO','EM') AND lot_type ='Production' and lot_id not like 'H%' and SUBSTR(lot_id,7,4) = '.00F' and ope_category in ('Ship','Unship') and YEAR(claim_time) = YEAR(current date -1 days) and month(claim_time) = month (current date -1 days) group by lot_id 请优化下这条sql
这个 SQL 查询中有一些可以优化的地方,以下是优化建议:
1. 使用别名缩短代码长度并提高可读性。
2. 使用 EXISTS 或者 INNER JOIN 来代替子查询,以提高查询效率。
3. 使用 BETWEEN 来代替 YEAR 和 MONTH 函数的组合使用,以提高查询效率。
4. 使用 IN 来代替多个 OR 条件的组合使用,以提高查询效率。
5. 删除无用的 else null,简化代码。
优化后的 SQL 查询如下所示:
SELECT
lot_id,
MAX(claim_time) AS claim_time,
COUNT(CASE WHEN open_category = 'Ship' THEN lot_id END) AS LS,
COUNT(CASE WHEN ope_category = 'Unship' THEN lot_id END) AS LUS
FROM
f3rpt.F3_TB_DAILY_FABOUT t1
WHERE
SUBSTR(lot_id, 1, 2) NOT IN ('CA', 'CW', 'ES', 'EO', 'EM')
AND lot_type = 'Production'
AND lot_id NOT LIKE 'H%'
AND SUBSTR(lot_id, 7, 4) = '.00F'
AND ope_category IN ('Ship', 'Unship')
AND claim_time BETWEEN DATE('now', '-1 day', 'start of month') AND DATE('now', '-1 day', 'start of month', '+1 month', '-1 day')
GROUP BY
lot_id;