【问题标题】:I'm seeking for better performance query我正在寻求更好的性能查询
【发布时间】:2021-10-05 12:11:04
【问题描述】:

我正在为这个问题寻找更好的解决方案

  1. 这里是数据集:https://8weeksqlchallenge.com/case-study-1/
  2. 在问题 9 中,即: “如果每消费 1​​ 美元相当于 10 分,而寿司有 2 倍的积分乘数 - 每个顾客会有多少积分?”
  3. 在这个问题中,我假设客户只有在成为会员后才能获得积分。之后,这是我的查询:
WITH CTE as -- Create CTE that includes customer_id, product_name, and Total Point broken by customer and product.
      (SELECT 
          s.customer_id customer, 
          m.product_name,
          count(s.product_id)*m.price*CAST(
                      CASE
                          WHEN m.product_name = 'sushi'
                              THEN 10*2
                          ELSE 10
                      END as int) Total_Point
      FROM sales s
      Join menu m
      ON s.product_id = m.product_id
      Join members mem
      On mem.customer_id = s.customer_id
      WHERE s.order_date >= mem.join_date
      GROUP BY s.customer_id, m.product_name, m.price
      ) 
  SELECT customer, sum(Total_Point) Total_Point
  FROM CTE
  GROUP BY customer

实际上我得到了回答问题的正确东西,但我认为它可以更好、更优化。

db<>fiddle

表定义为:

CREATE TABLE sales (
  "customer_id" VARCHAR(1),
  "order_date" DATE,
  "product_id" INTEGER
);

INSERT INTO sales
  ("customer_id", "order_date", "product_id")
VALUES
  ('A', '2021-01-01', '1'),
  ('A', '2021-01-01', '2'),
  ('A', '2021-01-07', '2'),
  ('A', '2021-01-10', '3'),
  ('A', '2021-01-11', '3'),
  ('A', '2021-01-11', '3'),
  ('B', '2021-01-01', '2'),
  ('B', '2021-01-02', '2'),
  ('B', '2021-01-04', '1'),
  ('B', '2021-01-11', '1'),
  ('B', '2021-01-16', '3'),
  ('B', '2021-02-01', '3'),
  ('C', '2021-01-01', '3'),
  ('C', '2021-01-01', '3'),
  ('C', '2021-01-07', '3');
 

CREATE TABLE menu (
  "product_id" INTEGER,
  "product_name" VARCHAR(5),
  "price" INTEGER
);

INSERT INTO menu
  ("product_id", "product_name", "price")
VALUES
  ('1', 'sushi', '10'),
  ('2', 'curry', '15'),
  ('3', 'ramen', '12');
  

CREATE TABLE members (
  "customer_id" VARCHAR(1),
  "join_date" DATE
);

INSERT INTO members
  ("customer_id", "join_date")
VALUES
  ('A', '2021-01-07'),
  ('B', '2021-01-09');

【问题讨论】:

  • 什么是表架构?索引?执行计划是什么?如果查询试图过滤或连接不是索引的字段,则必须扫描表中的所有行。无论有没有索引,相同的查询运行速度都可以提高数千倍
  • 到数据库的非站点链接没有帮助。如果您想在问题中包含数据库的详细信息,请在问题中添加 DDL 和 DML 语句。
  • 你不能指望我们阅读整篇文章。帮助我们帮助您。简化。
  • 虽然很多人,包括我自己(当我可以)使用小提琴,但这是为了补充答案,@Charlieface。我不会发布答案并说“您可以使用ROW_NUMBER,这是一个 [dbfiddle]”,并且不要在答案本身中发布解决方案。问题也是如此。小提琴应该补充这个问题,但不是必需的。
  • 很抱歉给您带来不便。我在这里完全是新手,我什至不知道什么是 index 和 fiddledb。感谢你们所有的 cmets 人,这对我找出我需要学习的东西有很大帮助。特别是,我非常感谢您的支持,查理! @查理脸

标签: sql sql-server


【解决方案1】:

您可以通过删除 CTE 来简化此查询,只需通过 customer 进行总结

SELECT 
  s.customer_id customer, 
  Total_Point = SUM(m.price * CASE WHEN m.product_name = 'sushi' THEN 20 ELSE 10 END)
FROM sales s
JOIN menu m ON s.product_id = m.product_id
JOIN members mem On mem.customer_id = s.customer_id
  AND s.order_date >= mem.join_date
GROUP BY
  s.customer_id;

db<>fiddle

我建议索引如下

sales (customer_id, order_date)

members (customer_id, join_date)

menu (product_id) INCLUDE (price, product_name)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-30
    • 1970-01-01
    • 2020-04-06
    • 2019-05-06
    • 1970-01-01
    • 2015-03-14
    相关资源
    最近更新 更多