Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
sql查询性能改进_Sql_Performance_Query Optimization - Fatal编程技术网

sql查询性能改进

sql查询性能改进,sql,performance,query-optimization,Sql,Performance,Query Optimization,我需要优化一个查询。我有两张桌子: tblcard(carid int,SerialNumber varchar(15),clientID) tblTransaction(TransactionID int,SerialNumber Varchar(15),transactiondatetime,) 我需要列出交易中涉及的所有卡的日期间隔、客户名称以及所有卡的首次交易日期 以下是我所做的: select tra.serialNumber, cli.clientName,

我需要优化一个查询。我有两张桌子:

  • tblcard
    carid int,SerialNumber varchar(15),clientID

  • tblTransaction
    TransactionID int,SerialNumber Varchar(15),transactiondatetime,

我需要列出交易中涉及的所有卡的日期间隔、客户名称以及所有卡的首次交易日期

以下是我所做的:

select 
   tra.serialNumber, 
   cli.clientName,
   (select top 1 tra.Transactiondate 
    from tblTransaction tra 
    where tra.SerialNumber = car.SerialNumber 
    order by tra.TransactionDate)
from 
   tblTransaction tra
left join 
   tblCard car on car.SerialNumber = tra.SerialNumber
left join 
   tblClient cli on car.ClientID = cli.ClientID
where 
   --date conditions

但考虑到事务非常多,此查询运行速度非常慢(超过3分钟)。你对如何优化这一点有什么想法吗?

执行计划会有所帮助。如果可能的话,用
内部连接替换
左侧连接可能会有所帮助。从性能的角度来看,使用子查询也是一个糟糕的想法。相反,您可能希望使用视图或CTE:

with LatestTransactions (SerialNumber, TransactionDate)
as
(
  select
   SerialNumber, max(TransactionDate) as TransactionDate
  from tblTransaction
  group by SerialNumber
)
select 
 tra.serialNumber, 
 cli.clientName,
 lt.TransactionDate
from tblTransaction tra
left join LatestTransactions lt on lt.SerialNumber = tra.SerialNumber
left join tblCard car on car.SerialNumber = tra.SerialNumber
left join tblClient cli on car.ClientID = cli.ClientID
where 
   --date conditions

当然,如果您没有使用正确的索引,它可能不会有多大帮助。这就是为什么查看查询执行计划很重要的原因。查询在哪里花费时间?为什么?您能否以合理的方式限制数据集?在某些列上引入新索引会有帮助吗?为什么要加入序列号,它是一个15个字符长的字符串,而不是某个标识列?

Luaan,你的答案很好,我认为这是一个更可读的答案(不管tblclient表是否缺失)


尝试将子查询替换为
密集\u秩
聚合(oracle语法):


可能遗漏了一些索引。执行计划可以澄清这一点。

请提供有关所用DBMS、现有索引、日期条件示例和执行计划的信息。有关第三个表
tblClient
和示例输出的信息也会有所帮助。
select tblTransaction.TransactionDate, Mindate.SerialNumber, Mindate.TransactionDate 
from tblTransaction
outer apply (select MIN(tra.Transactiondate) TransactionDate, car.SerialNumber 
            from tblTransaction tra 
            INNER JOIN tblCard car on car.SerialNumber = tra.SerialNumber
            where car.SerialNumber = tblTransaction.SerialNumber group by car.SerialNumber) Mindate
where tblTransaction.TransactionDate between '2013-05-05' and '2014-05-05'
select
   tra.serialNumber, 
   cli.clientName,
   MIN(tra.Transactiondate)
       KEEP (DENSE_RANK FIRST ORDER BY tra.TransactionDate)
       OVER (PARTITION BY tra.SerialNumber) AS transactiondate
from 
   tblTransaction tra
left join 
   tblCard car on car.SerialNumber = tra.SerialNumber
left join 
   tblClient cli on car.ClientID = cli.ClientID
where 
   --date conditions