如何加快更新速度 SQL

How To Speed Up Update SQL

我在 Delphi 2010 年使用 ADScript 组件执行了 480 个更新 SQL 语句。

Update SQL 仅更新一个名为 MY_BOOK 的 table 中的数据,但存在与 MY_BOOK_HEADER table 的连接。下面是 Update SQL,执行所有 480 条 Update SQL 语句需要 81 秒。知道如何提高这些 480 更新 SQL 语句的速度吗?

更新SQL:

Update MY_BOOK MB SET BOOK_NAME = 'Book Name1' , BOOK_DESCRIPTION = 'Book Desfcription1' 
Where MB.BOOK_TYPE = 4 And 
Exists (Select 1 from MY_BOOK_HEADER MBH 
            Where  
                MBH.HEADER_BOOK_CODE = '127518010109038'
                And MBH.FK_BOOK_GROUP =  '{79B79C33-CE56-4084-912B-6DD9F70B3DC4}'
                And MBH.PK_BOOK_HEADER = MB.SK_BOOK_HEADER
        );

您可以使用 merge 语句,像这样....:[=​​12=]

merge into MY_BOOK MB
using MY_BOOK_HEADER MBH
  on (MB.SK_BOOK_HEADER = MBH.PK_BOOK_HEADER and
      MB.BOOK_TYPE = 4 and
      MBH.HEADER_BOOK_CODE = '127518010109038' and
      MBH.FK_BOOK_GROUP =  '{79B79C33-CE56-4084-912B-6DD9F70B3DC4}')
when matched then
  update set
    MB.BOOK_NAME = 'Book Name1',
    MB.BOOK_DESCRIPTION = 'Book Desfcription1';

参考:http://www.firebirdsql.org/refdocs/langrefupd21-merge.html

下面的答案是我从 Firebird 组得到的。本回答仅供知识分享。

来自 Firebird Group 的评论如下,其中还包括 Execute Block 语句:

如果 PK 是 MY_BOOK 的整数主键,那么您应该能够 做这样的事情:

execute block returns(Changes integer) as
declare variable mbPK integer;
begin
Changes = 0;
for select distinct MB.PK
from MY_BOOK MB
join MY_BOOK_HEADER MBH on MBH.PK_BOOK_HEADER = MB.SK_BOOK_HEADER
where MB.BOOK_TYPE = 4
and Upper(Trim(MBH.HEADER_BOOK_CODE)) = Upper(Trim('127518010109038'))
--UPPER and TRIM doesn't make any difference to a constant containing 
--only digits and no whitespace...
And MBH.FK_BOOK_GROUP = '{79B79C33-CE56-4084-912B-6DD9F70B3DC4}'
into :mbPK do
begin
update My_Book SET BOOK_NAME = 'Book Name1', BOOK_DESCRIPTION = 
'Book Description1'
where PK = :mbPK;
Changes = Changes + ROW_COUNT;
end
suspend;
end

'Changes' 和 'suspend' 不是必需的,但每当我使用 EXECUTE BLOCK myself,我更愿意添加这样一个变量来确定我只 更新我要更新的十条记录而不是一百万条记录,因为 忘记了 JOIN 或 WHERE 子句中的重要内容。

我认为如果

执行块可以特别提高性能

a) 您只想减少 My_Book 中的一小部分记录, and/or b) EXISTS 子句复杂且耗时

如果My_Book和My_Book_Header都是小表 索引,使用执行块可能帮助很小或没有帮助。