暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle OTLT (一个真正的大表) 与单独的小表

ASKTOM 2021-05-19
733

问题描述

OTLT (一个真正的大表) 是否由于锁定或任何其他原因而降低了查询性能,
当它被左连接或用于标量子查询时,多次如下?

将OTLT拆分为单独的表是否提供了更好的性能?

CREATE TABLE AUTO
(
ID NUMBER ,
TYPE VARCHAR2(10),
NAME VARCHAR2(10)
CONSTRAINT PK_AUTO PRIMARY KEY (ID)
) 

SELECT * FROM AUTO;

ID TYPE NAME
1 CAR FORD
2 CAR DODGE
3 CAR FIAT
4 CAR BENZ
5 CAR BMW
6   SUV JEEP
7   SUV VOLVO
8   SUV TOYOTA
9   SUV KIA
10  TRK OSKOSH
11  TRK DAIMLER
12  TRK MACK
13  TRK HINO

CREATE TABLE STOCK
(
ID NUMBER ,
LOCATION VARCHAR2(100),
CAR_ID NUMBER,
SUV_ID NUMBER,
TRK_ID NUMBER
CONSTRAINT PK_STOCK PRIMARY KEY (ID)
);

ALTER TABLE STOCK ADD CONSTRAINT FK_STOCK_AUTO_CAR FOREIGN KEY (CAR_ID) REFERENCES AUTO(ID);
ALTER TABLE STOCK ADD CONSTRAINT FK_STOCK_AUTO_SUV FOREIGN KEY (SUV_ID) REFERENCES AUTO(ID);
ALTER TABLE STOCK ADD CONSTRAINT FK_STOCK_AUTO_TRK FOREIGN KEY (TRK_ID) REFERENCES AUTO(ID);

CREATE INDEX IDX_FK_STOCK_AUTO_CAR ON STOCK(CAR_ID);
CREATE INDEX IDX_FK_STOCK_AUTO_SUV ON STOCK(SUV_ID);
CREATE INDEX IDX_FK_STOCK_AUTO_TRK ON STOCK(TRK_ID);

SELECT * FROM STOCK;
ID LOCATION CAR_ID SUV_ID TRK_ID
1  VA   1       8    13
2  MD        NULL    6     10   
3  NC        8       NULL  5

SELECT 
 STK.LOCATION,
 CAR.NAME CAR_NAME,
 SUV.NAME  SUV_NAME,
 TRK.NAME TRK_NAME
FROM 
 STOCK STK
LEFT JOIN  
     AUTO CAR ON STK.CAR_ID = CAR.ID
LEFT JOIN  
     AUTO SUV ON SUV.SUV_ID = SUV.ID
LEFT JOIN  
     AUTO TRK ON TRK.TRK_ID = TRK.ID
WHERE STK.LOCATION ='VA';  


-------------------- 或 -----------------------------

SELECT 
 STK.LOCATION,
 (SELECT CAR.NAME FROM AUTO CAR WHERE STK.CAR_ID = CAR.ID) CAR_NAME,
 (SELECT SUV.NAME FROM AUTO SUV WHERE STK.SUV_ID = SUV.ID) SUV_NAME,
 (SELECT TRK.NAME FROM AUTO TRK WHERE TRK.TRK_ID = TRK.ID) TRK_NAME,
WHERE STK.LOCATION ='VA';  

----------------
LOCATION   CAR_NAME  SUV_NAME  TRK_NAME
VA          FORD      TOYOTA      HINO   

专家解答

due to locks or any other reason

在我之后重复:

Oracle数据库acquire中的查询NO数据锁。

因此,无论您使用哪种设计,这都没有区别。

Does splitting OTLT into separate table, provides better performance?

也许吧。将一个表分成多个表有两个优点:

-表较小,因此完全扫描表要读取的数据较少 => 更快
-通常,优化器更容易估计从每个表中获得多少行 => 更好的计划 => 更快

所以单独的查找表更有可能给出更快的查询。在实践中,如果计划具有有效的索引查找,则可能几乎没有差异。

我不会真的把这个例子归类为OTLT。它更像是超类型/子类型关系的一个例子。你几乎肯定想要超级类型的自动表,可能有单独的子表来存储汽车、suv等的特定细节。

而不是为库存表中的每种类型单独的列,我会添加一个自动类型列:

CREATE TABLE STOCK
(
ID NUMBER ,
LOCATION VARCHAR2(100),
AUTO_ID NUMBER,
AUTO_TYPE NUMBER,
CONSTRAINT PK_STOCK PRIMARY KEY (ID)
);


然后,您可以加入一次自动表。

如果您需要输出的列式格式,则可以始终使用PIVOT

https://blogs.oracle.com/sql/how-to-convert-rows-to-columns-and-back-again-with-sql-aka-pivot-and-unpivot
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论