惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

量子位
小众软件
小众软件
S
SegmentFault 最新的问题
人人都是产品经理
人人都是产品经理
博客园 - 【当耐特】
博客园 - 三生石上(FineUI控件)
C
Check Point Blog
S
Schneier on Security
Microsoft Azure Blog
Microsoft Azure Blog
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
罗磊的独立博客
有赞技术团队
有赞技术团队
V
V2EX
Y
Y Combinator Blog
博客园 - 叶小钗
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
F
Fortinet All Blogs
W
WeLiveSecurity
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
The Cloudflare Blog
S
Security @ Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
MyScale Blog
MyScale Blog
Hugging Face - Blog
Hugging Face - Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
www.infosecurity-magazine.com
www.infosecurity-magazine.com
PCI Perspectives
PCI Perspectives
H
Heimdal Security Blog
Schneier on Security
Schneier on Security
Security Latest
Security Latest
AWS News Blog
AWS News Blog
月光博客
月光博客
Security Archives - TechRepublic
Security Archives - TechRepublic
Recent Announcements
Recent Announcements
Google DeepMind News
Google DeepMind News
博客园 - Franky
Cisco Talos Blog
Cisco Talos Blog
T
Threat Research - Cisco Blogs
M
MIT News - Artificial intelligence
T
Troy Hunt's Blog
N
News and Events Feed by Topic
Cloudbric
Cloudbric
Scott Helme
Scott Helme
云风的 BLOG
云风的 BLOG
Attack and Defense Labs
Attack and Defense Labs

博客园 - levin

如何读取内存的数据?(转) ECC 6.0 安装之后的配置(转) 网络分析中数据包结构的定义 网络管理之数据包的解释与结构分析(转) SAP BDC 技术的分类(转) Delphi中建议使用的语句 Delphi面向对象编程的20条规则 Delphi取整函数 ECC 6.0 New GL Functionality and General FAQ - levin Delphi中的容器类 BDC教程(转) - levin - 博客园 SAP BDC批量导入数据(转) - levin - 博客园 Master data-Customer 如何快速从BSEG读取数据(转) 刷新ALV定位到当前记录行 - levin - 博客园 双击ALV调用事务代码并传入参数 如何查找系统屏幕参数 一些常用的系统变量(SYST) ABAP内表(internal table)有关的系统变量 ABAP字符串比较操作中空格的影响
Rules for Better SQL Programming
levin · 2009-08-04 · via 博客园 - levin

Always try to keep the hit list small by using the where clause were ever required or by describing the full search condition in the where clause.
Select Query #1
Wrong

SELECT * FROM sflight INTO xflight.
CHECK xflight-carrid = 'LH '.
CHECK xflight-connid = '0300'.
CHECK xflight-fldate(4) = '2002'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

SELECT * FROM sflight INTO xflight
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Select Query #2
Wrong

 SELECT * FROM sflight INTO xflight
WHERE carrid = 'LH ' AND connid = '0300'.
CHECK xflight-fldate(4) = '2002'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

 SELECT * FROM sflight INTO xflight
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Tip #2 : Minimize the Amount of Transferred Data

Minimize the amount of data transferred between the database and the application server.

Wrong

SELECT * FROM sflight INTO xflight WHERE carrid = 'LH '
AND connid = '0300'
AND fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

SELECT fldate FROM sflight INTO (xflight-fldate) WHERE carrid = 'LH '
AND connid = '0300'
AND fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Apply UP TO n ROWS.

Wrong

SELECT id name discount FROM scustom INTO (xid, xname, xdiscount)
WHERE custtype = 'B'
ORDER BY discount.
IF sy-dbcnt > 10. EXIT. ENDIF.
WRITE: / xid, xname, xdiscount.
ENDSELECT.

Right

SELECT id name discount
FROM scustom UP TO 10 ROWS
INTO (xid, xname, xdiscount)
WHERE custtype = 'B'
ORDER BY discount.
WRITE: / xid, xname, xdiscount.
ENDSELECT.

or how about using SELECT SINGLE instead of SELECT UP TO 1 ROWS.

Use the UPDATE … SET Statement

Wrong

SELECT * FROM sflight
INTO xflight
WHERE carrid ='LH '.
xflight-seatsocc = xflight-seatsocc + 1.
UPDATE sflight FROM xflight.
ENDSELECT.

Right

UPDATE sflight
SET seatsocc = seatsocc + 1
WHERE carrid = 'LH '.

Use aggregate functions

Wrong

sum = 0.
SELECT seatsocc
FROM sflight INTO xseatsocc
WHERE fldate LIKE '2002%'.
sum = sum + xseatsocc.
ENDSELECT.
WRITE: / sum.

Right

SELECT SINGLE SUM( seatsocc )
FROM sflight INTO sum
WHERE fldate LIKE '2002%'.
WRITE: / sum.

Apply Having Clause

Wrong

SELECT carrid connid fldate MAX( luggweight )
INTO (xcarrid, xconnid, xfldate, max)
FROM sbook
GROUP BY carrid connid fldate.
CHECK max gt 20.
WRITE: / xcarrid, xconnid, xfldate, max.
ENDSELECT.

Right

SELECT carrid connid fldate MAX( luggweight )
INTO (xcarrid, xconnid, xfldate, max)
FROM sbook
GROUP BY carrid connid fldate
HAVING MAX( luggweight ) gt 20.
WRITE: / xcarrid, xconnid, xfldate, max.
ENDSELECT.

Tip #3: Keep the number of round trips between the database and the application server small.

Use high-speed array operations with UPDATE, INSERT, DELETE, MODIFY.

Wrong

LOOP AT itab INTO wa.
INSERT INTO sbook VALUES wa.
ENDLOOP.

Right

INSERT sbook FROM TABLE itab.

Apply the INNER JOIN. Avoid nested SELECT-ENDSELECT loops

Wrong

SELECT * FROM sflight INTO xflight WHERE planetype = '727-200'.
SELECT * FROM sbook INTO xbook
WHERE carrid = xflight-carrid AND
connid = xflight-connid AND
fldate = xsflight-fldate.
WRITE: / xflight-carrid, xflight-connid, xbook-bookid.
ENDSELECT.
ENDSELECT.

Right

SELECT f~carrid f~connid b~bookid
INTO (xcarrid, xconnid, xbookid)
FROM sflight AS f INNER JOIN sbook AS b
ON f~carrid = b~carrid AND
f~connid = b~connid AND
f~fldate = b~fldate
WHERE planetype = '727-200'.
WRITE: / xcarrid, xconnid, xbookid.
ENDSELECT.

Apply the OUTER JOIN

Wrong

SELECT * FROM sflight INTO xflight WHERE planetype = '727-200'.
SELECT * FROM sbook INTO xbook
WHERE carrid = xflight-carrid
AND connid = xflight-connid
AND fldate = xflight-fldate.
WRITE: / xflight-carrid, xflight-connid, xflight-fldate,
xbook-bookid.
ENDSELECT.
IF sy-dbcnt = 0.
CLEAR xbook-bookid.
WRITE: / xflight-carrid, xflight-connid, xflight-fldate,
xbook-bookid.
ENDIF.
ENDSELECT.

Right

SELECT f~carrid f~connid f~fldate b~bookid
INTO (xcarrid, xconnid, xfldate, xbookid)
FROM sflight AS f LEFT OUTER JOIN sbook AS b
ON f~carrid = b~carrid AND f~connid = b~connid
AND f~fldate = b~fldate.
WHERE planetype = '727-200'.
WRITE: / xcarrid, xconnid, xfldate, xbookid.
ENDSELECT.

Use subqueries

Wrong

SELECT carrid connid MAX( seatsocc )
FROM sflight
INTO (xcarrid, xconnid, max)
GROUP BY carrid connid
ORDER BY carrid connid.
SELECT fldate FROM sflight
INTO yfldate
WHERE carrid = xcarrid AND
connid = xconnid AND
seatsocc = max
ORDER BY fldate.
WRITE: / xcarrid, xconnid, yfldate.
ENDSELECT.
ENDSELECT.

Right

SELECT carrid connid fldate
FROM sflight AS f
INTO (xcarrid, xconnid, xfldate)
WHERE seatsocc IN
( SELECT MAX( seatsocc ) FROM sflight
WHERE carrid = f~carrid AND connid = f~connid )
ORDER BY carrid connid fldate.
WRITE: xcarrid, xconnid, xfldate.
ENDSELECT.

For frequently used INNER JOINs, you can create a database view in the ABAP Dictionary

Wrong

SELECT f~carrid f~connid b~bookid
INTO (xcarrid, xconnid, xbookid)
FROM sflight AS f INNER JOIN sbook AS b
ON f~carrid = b~carrid AND f~connid = b~connid
AND f~fldate = b~fldate.
WRITE: / xcarrid, xconnid, xbookid.
ENDSELECT.

Right

SELECT carrid connid bookid
INTO (xcarrid, xconnid, xbookid)
FROM sflightbook.
WRITE: / xcarrid, xconnid, xbookid.
ENDSELECT.

Tip #4: Keep the Cost of the Search Down
Specify the WHERE clause to keep the number of searches down and create suitable indices if necessary.

Wrong

SELECT bookid FROM sbook INTO xflight
WHERE orderdate = '20020304'.
WRITE: / xbookid.
ENDSELECT.

Right

SELECT bookid
FROM sbook INTO xbookid
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate = '20020304'.
WRITE: / xbookid.
ENDSELECT.


Make sure that the first n fields of the designated index are stated with EQ within the WHERE clause.

Wrong

SELECT * FROM sflight INTO xflight
WHERE carrid = 'LH ' AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

SELECT * FROM sflight
INTO xflight
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Replace the inner OR with an IN operator

Wrong

SELECT * FROM sflight
INTO xflight
WHERE carrid = 'LH ' AND
(connid = '0300' OR connid = '0302') AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

SELECT * FROM sflight
INTO xflight
WHERE carrid = 'LH ' AND
connid IN ('0300', '0302') AND
fldate LIKE '2002%'.
WRITE: / xflight-fldate.
ENDSELECT.

You cannot process NOT operators in SELECT using an index.

Wrong

SELECT * FROM sflight
INTO xflight
WHERE carrid <> 'LH ' AND
connid = '0300'.
WRITE: / xflight-fldate.
ENDSELECT.

Right

SELECT * FROM sflight
INTO xflight
WHERE carrid IN ('AA ', 'QM ') AND
connid = '0300'.
WRITE: / xflight-fldate.
ENDSELECT.

Think about optimizer hints if the optimizer fails to find a sound execution plan.

Wrong

SELECT carrid connid cityfrom
FROM spfli INTO (xcarrid, xconnid, xcityfrom)
WHERE carrid = 'LH ' AND cityfrom = 'FRANKFURT'.
WRITE: / xcarrid, xconnid, xcityfrom.
ENDSELECT.

Right

SELECT carrid connid cityfrom
FROM spfli INTO (xcarrid, xconnid, xcityfrom)
WHERE carrid = 'LH ' AND cityfrom = 'FRANKFURT'
%_HINTS ORACLE 'INDEX("SPFLI" "SPFLI~001")'.
WRITE: / xcarrid, xconnid, xcityfrom.
ENDSELECT.

Tip #5. Remove the load from the database.

Check if the table meets the criteria for table buffering. When applying the table buffering check if the table is frequently read, should be relatively small and deferred visibility of changes is acceptable.

Do not apply table buffering for tables which are changed heavily or if the contents of the table must be always up-to-date.

Ensure that you use the correct SELECT STATEMENT. Here are some of the statements which bypass the table buffer.

SELECT ... DISTINCT
SELECT ... COUNT, SUM, AVG, MIN, MAX
SELECT ... ORDER BY f1 ... fn
SELECT ... GROUP BY / HAVING
SELECT ... FOR UPDATE
SELECT ... JOIN
WHERE clause contains IS NULL statement
WHERE clause contains subquery
SELECT ... BYPASSING BUFFER


Avoid reading the same data again and again.

Wrong

SELECT SINGLE * FROM scarr
INTO xcarr
WHERE carrid = 'LH '.
...
SELECT SINGLE * FROM scarr
INTO zcarr
WHERE carrid = 'LH '.

Right

SELECT SINGLE * FROM scarr
INTO xcarr
WHERE carrid = 'LH '.
 
zcarr = xcarr.

Check whether a SELECT is really needed before an UPDATE is made.

Wrong

SELECT SINGLE * FROM sflight
INTO xflight
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate = '20021204'.
xflight-seatsocc = 1.
UPDATE sflight FROM xflight.

Right

UPDATE sflight
SET seatsocc = 1
WHERE carrid = 'LH ' AND
connid = '0300' AND
fldate = '20021204'.

Avoid the ORDER BY clause if the desired sorting doesn’t correspond to the index used.

Wrong

SELECT p~airpfrom p~airpto f~fldate p~deptime
INTO xflight
FROM spfli AS p INNER JOIN sflight AS f
ON p~carrid = f~carrid
AND p~connid = f~connid
WHERE p~carrid = 'LH '
ORDER BY p~airpfrom p~airpto f~fldate p~deptime.
WRITE: / xflight-airpfrom, xflight-airpto,
xflight-fldate, xflight-deptime.
ENDSELECT.

Right

SELECT p~airpfrom p~airpto f~fldate p~deptime
INTO TABLE flights
FROM spfli AS p INNER JOIN sflight AS f
ON p~carrid = f~carrid
AND p~connid = f~connid
WHERE p~carrid = 'LH '.
SORT flights BY airpfrom airpto fldate deptime.
LOOP AT flights INTO xflight.
WRITE: / xflight-airpfrom, xflight-airpto,
xflight-fldate, xflight-deptime.
ENDLOOP.