我有一個存盤來自某些 API 的回應的表。它有 170 萬行。pk 是 UnixTime 的一種(不完全是,但很簡單)。我非常頻繁地呼叫 API 以查看資料是否已更改。要檢查資料是否已更改,我必須運行以下命令:
SELECT 1
FROM RATE
WHERE REGDATE = '$apiReponseDate' --yymmddhhmmss
如果答案是False,則表示回應已更改,然后我插入。我在 REGDATE 上有一個索引,我知道這會使表進行二進制搜索,而不是完全搜索。
但我確實知道,為了知道資料是否已更新,我只需要檢查最近的行。對我來說,對整個表使用 WHERE 似乎是一種低效的方法。
有什么好方法可以查看我從 API 回應中獲得的資料是否已經在資料庫中?我正在使用 Oracle,但這不是重點,因為我正在考慮搜索查詢的效率。
uj5u.com熱心網友回復:
您可以使用index_desc提示和過濾依據rownum來訪問表并讀取最新的行。然后將此值與當前 API 回應進行比較。
下面是(默認)升序索引的示例。如果索引創建為id desc,則需要顛倒閱讀順序(指定index_asc提示)。
create table t ( id not null, val ) as select level, dbms_random.string('x', 1000) from dual connect by level < 5000 create unique index t_ix on t(id)select /* index_desc(t (t.id)) gather_plan_statistics */ id, substr(val, 1, 10) from t where rownum = 1
ID SUBSTR(VAL,1,10) 4999 D0H3YOHB5E
select * from dbms_xplan.display_cursor( format => 'ALL ALLSTATS' )
PLAN_TABLE_OUTPUT :----------------- SQL_ID 2ym2rg02qfmk4, child number 0 ------------------------------------- select /* index_desc(t (t.id)) gather_plan_statistics */ id, substr(val, 1, 10) from t where rownum = 1 ? Plan hash value: 1335626365 ? ------------------------------------------------------------------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows |E-Bytes| Cost (%CPU)| E-Time | A-Rows | A-Time | Buffers | Reads | ------------------------------------------------------------------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | | 3 (100)| | 1 |00:00:00.01 | 3 | 1 | |* 1 | COUNT STOPKEY | | 1 | | | | | 1 |00:00:00.01 | 3 | 1 | | 2 | TABLE ACCESS BY INDEX ROWID BATCHED| T | 1 | 1 | 1005 | 3 (0)| 00:00:01 | 1 |00:00:00.01 | 3 | 1 | | 3 | INDEX FULL SCAN DESCENDING | T_IX | 1 | 4999 | | 2 (0)| 00:00:01 | 1 |00:00:00.01 | 2 | 1 | ------------------------------------------------------------------------------------------------------------------------------------------------ ? Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- ? ???1 - SEL$1 ???2 - SEL$1 / "T"@"SEL$1" ???3 - SEL$1 / "T"@"SEL$1" ? Predicate Information (identified by operation id): --------------------------------------------------- ? ???1 - filter(ROWNUM=1) ? Column Projection Information (identified by operation id): ----------------------------------------------------------- ? ???1 - "ID"[NUMBER,22], "VAL"[VARCHAR2,4000] ???2 - "ID"[NUMBER,22], "VAL"[VARCHAR2,4000] ???3 - "T".ROWID[ROWID,10], "ID"[NUMBER,22] ? Hint Report (identified by operation id / Query Block Name / Object Alias): Total hints for statement: 1 --------------------------------------------------------------------------- ? ???2 - SEL$1 / "T"@"SEL$1" ???????????- index_desc(t (t.id))
小提琴
uj5u.com熱心網友回復:
而不是做 a SELECTand then INSERT,這是兩個查詢,然后你可以將兩者組合成一個MERGE陳述句:
MERGE INTO rate r
USING DUAL ignore
ON r.redgate = '$apiReponseDate'
WHEN NOT MATCHED THEN
INSERT (col1, col2, col3, redgate)
VALUES ('value1', 'value2', 'value3', '$apiNewReponseDate');
這將避免您必須使用從中間層到資料庫的兩次往返,并在單個查詢中完成所有操作。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533107.html
標籤:sql甲骨文
