【问题标题】:How can increase the performance of the query below without using distinct keyword如何在不使用 distinct 关键字的情况下提高以下查询的性能
【发布时间】:2019-12-15 15:13:20
【问题描述】:

我有 2 个表来记录数据。例如,如果您登录,您的信息将记录到 table1 中。当您第二次登录时,您的信息被记录到表1中,您之前的输入信息转移到表2中。表格的行太多。最后,我想获取过去 60 天内使用给定 IP 地址登录的不同用户的数量。 ip 是 sql 语句的输入。但是,我的 sql 查询存在性能问题。 (两个表具有相同的结构,请忽略您的建议的索引)另外,是使用没有 distinct 和另一个 select 关键字来获取 totCount 的任何方法。 谢谢

这是我的 sql:

 select distinct count(*) over() as totCount 
 into p_differentCustomerCount
 from (
      select t1.customerNo,t1.customerIp,t1.lastlogindate from table1 t1
      union all 
      select t2.customerNo,t2.customerIp,t2.lastlogindate from table2 t2
      )t
 where t.lastlogindate > sysdate - 60 
       and t.customerIp= "IP_As_Input"
 group by customerNo;

【问题讨论】:

  • 删除union all。它什么也没做。您的描述提到了两个表,但您的查询只引用了一个。
  • 您是否希望每个 ip 使用相同 ip 登录的不同用户的数量?还是只是总数?明确你想要什么。

标签: sql oracle plsql


【解决方案1】:

您需要知道使用相同 ip 登录的不同用户的count。所以我的建议是直接使用where 子句。不在内部视图中。

类似这样的:

select count(1) as totCount 
 into p_differentCustomerCount
 from (
      select customerNo 
        from table1
       Where lastlogindate > sysdate - 60 
         And customerIp= 'IP_As_Input'
      union -- gives distinct result
      select customerNo 
        from table2
       Where lastlogindate > sysdate - 60 
         And customerIp= 'IP_As_Input'
      )

干杯!!

【讨论】:

    【解决方案2】:

    我想获取过去 60 天内使用相同 IP 登录的不同用户的数量。

    你似乎想要:

    select count(*)
    from table1 t1
    where not exists (select 1
                      from table2 t2
                      where t2.customerNo = t1.customerNo and
                            t2.customerIp <> t1.customerIp and
                            t2.lastlogindate >= sysdate - 60
                     );
    

    我不知道你为什么在 ip 上有一个过滤器。文中并未提及。

    【讨论】:

    • Ip 作为输入传递给 sql 查询。所以我必须使用它。
    【解决方案3】:

    我想获取过去 60 天内使用相同 IP 登录的不同用户的数量。

    您似乎想使用COUNT(DISTINCT CUSTOMERNO),而不是DISTINCT COUNT(*)

    SELECT COUNT(DISTINCT z.CUSTOMERNO) AS CUSTOMER_COUNT
      FROM (SELECT * FROM TABLE1
            UNION ALL
            SELECT * FROM TABLE2) z
      WHERE z.CUSTOMERIP = 'wh.at.ev.ah' AND
            z.LASTLOGINDATE > SYSDATE - INTERVAL '60' DAY
    

    但是你说你不想使用DISTINCT 关键字。很好:

    SELECT SUM(RN) AS CUSTOMER_COUNT
      FROM (SELECT ROW_NUMBER() OVER (PARTITION BY z.CUSTOMER_NO) AS RN
              FROM (SELECT * FROM TABLE1
                    UNION ALL
                    SELECT * FROM TABLE2) z
              WHERE z.CUSTOMERIP = 'wh.at.ev.ah' AND
                    z.LASTLOGINDATE > SYSDATE - INTERVAL '60' DAY
              HAVING RN = 1)
    

    【讨论】:

    • 贾维斯 - 恢复,是的,但我必须通过 3 个选择语句来解决它
    猜你喜欢
    • 2015-07-01
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 2010-09-19
    • 2021-10-28
    • 2015-10-19
    • 2015-05-29
    • 2016-01-17
    相关资源
    最近更新 更多