一、 count(1)與count(*),count(列明)區別
執行效果:
1. count(1) and count(*)
當表的數據量大些時,對錶作分析之後,使用count(1)還要比使用count(*)用時多了!
從執行計劃來看,count(1)和count(*)的效果是一樣的。 但是在表做過分析之後,count(1)會比count(*)的用時少些(1w以內數據量),不過差不了多少。
如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。
因爲count(*),自動會優化指定到那一個字段。所以沒必要去count(1),用count(*),sql會幫你完成優化的 因此:count(1)和count(*)基本沒有差別!
2. count(1) and count(字段)
兩者的主要區別是
(1) count(1) 會統計表中的所有的記錄數,包含字段爲null 的記錄。
(2) count(字段) 會統計該字段在表中出現的次數,忽略字段爲null 的情況。即不統計字段爲null 的記錄。
轉自:http://www.cnblogs.com/Dhouse/p/6734837.html
3.count(*) 和 count(1)和count(列名)區別
執行效果上:
count(*)包括了所有的列,相當於行數,在統計結果的時候,不會忽略列值爲NULL
count(1)包括了忽略所有列,用1代表代碼行,在統計結果的時候,不會忽略列值爲NULL
count(列名)只包括列名那一列,在統計結果的時候,會忽略列值爲空(這裏的空不是隻空字符串或者0,而是表示null)的計數,即某個字段值爲NULL時,不統計。
執行效率上:
列名爲主鍵,count(列名)會比count(1)快
列名不爲主鍵,count(1)會比count(列名)快
如果表多個列並且沒有主鍵,則 count(1) 的執行效率優於 count(*)
如果有主鍵,則 select count(主鍵)的執行效率是最優的
如果表只有一個字段,則 select count(*)最優。
==========================================================
二、 in 和 exists的區別
in是把外表和內表作hash連接,而exists是對外表作loop循環,每次loop循環再對內表進行查詢,一直以來認爲exists比in效率高的說法是不準確的。如果查詢的兩個表大小相當,那麼用in和exists差別不大;如果兩個表中一個較小一個較大,則子查詢表大的用exists,子查詢表小的用in;
例如:表A(小表),表B(大表)
select * from A where cc in(select cc from B) -->效率低,用到了A表上cc列的索引; select * from A where exists(select cc from B where cc=A.cc) -->效率高,用到了B表上cc列的索引。
相反的:
select * from B where cc in(select cc from A) -->效率高,用到了B表上cc列的索引 select * from B where exists(select cc from A where cc=B.cc) -->效率低,用到了A表上cc列的索引。
2、not in 和not exists
not in 邏輯上不完全等同於not exists,如果你誤用了not in,小心你的程序存在致命的BUG,請看下面的例子:
create table #t1(c1 int,c2 int); create table #t2(c1 int,c2 int); insert into #t1 values(1,2); insert into #t1 values(1,3); insert into #t2 values(1,2); insert into #t2 values(1,null); select * from #t1 where c2 not in(select c2 from #t2); -->執行結果:無 select * from #t1 where not exists(select 1 from #t2 where #t2.c2=#t1.c2) -->執行結果:1 3
正如所看到的,not in出現了不期望的結果集,存在邏輯錯誤。如果看一下上述兩個select 語句的執行計劃,也會不同,後者使用了hash_aj,所以,請儘量不要使用not in(它會調用子查詢),而儘量使用not exists(它會調用關聯子查詢)。如果子查詢中返回的任意一條記錄含有空值,則查詢將不返回任何記錄。如果子查詢字段有非空限制,這時可以使用not in,並且可以通過提示讓它用hasg_aj或merge_aj連接。
如果查詢語句使用了not in,那麼對內外表都進行全表掃描,沒有用到索引;而not exists的子查詢依然能用到表上的索引。所以無論哪個表大,用not exists都比not in 要快。
3、in 與 = 的區別
select name from student where name in('zhang','wang','zhao');
與
select name from student where name='zhang' or name='wang' or name='zhao'
的結果是相同的。
===========================================
三、表的分區類型說明
A.創建range分區,一般用於日期化處理,range分區可以很好的管理基於日期來分區的數據
創建一個新用戶ls
SYS@LEO> create user ls identified by ls;
SYS@LEO> grant dba to ls;
SYS@LEO> conn ls/ls
創建樣本數據表
create table liusheng (orderid number(10),name varchar2(10),ls_date date);
insert into liusheng values (1,'ls1',to_date('1981-01-02','yyyy-mm-dd'));
insert into liusheng values (1,'ls2',to_date('1998-01-03','yyyy-mm-dd'));
insert into liusheng values (1,'ls3',to_date('1999-01-04','yyyy-mm-dd'));
insert into liusheng values (1,'ls4',to_date('2000-01-05','yyyy-mm-dd'));
insert into liusheng values (1,'ls5',to_date('2000-01-06','yyyy-mm-dd'));
insert into liusheng values (1,'ls6',to_date('2001-01-07','yyyy-mm-dd'));
insert into liusheng values (1,'ls7',to_date('2001-01-08','yyyy-mm-dd'));
insert into liusheng values (1,'ls8',to_date('2002-01-09','yyyy-mm-dd'));
insert into liusheng values (1,'ls9',to_date('2002-01-10','yyyy-mm-dd'));
insert into liusheng values (1,'ls10',to_date('2011-01-11','yyyy-mm-dd'));
創建range分區表
create table liusheng_part
partition by range (ls_date)
(
partition liusheng_part_1999_1 values less than (to_date('1999-01-01','yyyy-mm-dd')) ,
partition liusheng_part_2000_1 values less than (to_date('2000-01-01','yyyy-mm-dd')) ,
partition liusheng_part_2001_1 values less than (to_date('2001-01-01','yyyy-mm-dd')) ,
partition liusheng_part_2002_1 values less than (to_date('2002-01-01','yyyy-mm-dd')) ,
partition liusheng_part_2003_1 values less than (to_date('2003-01-01','yyyy-mm-dd')) ,
partition other values less than (maxvalue)
)
as select * from liusheng;
查看分區
select * from liusheng_part partition (liusheng_part_1999_1);
select * from liusheng_part partition (liusheng_part_2000_1);
select * from liusheng_part partition (liusheng_part_2001_1);
select * from liusheng_part partition (liusheng_part_2002_1);
select * from liusheng_part partition (liusheng_part_2003_1);
select * from liusheng_part partition (other);
B.創建hash分區,利用hash函數打散某列使數據均勻分佈,一般用於均衡I/O,缺點數據不容易管理,哈希分區不能DROP、SPLIT 以及MERGE分區
我們創建了擁有10個分區的哈希分區表“LIUSHENG_HASH”
LS@LEO> create table liusheng_hash partition by hash(object_id) partitions 10 as select * from dba_objects;
hash分區所佔用的區個數,看每個分區佔用的個數都差不多,說明數據還是比較均勻分佈的
缺點:hash列上數值不能有太多的重複值,否則會導致數據分佈不均勻
select partition_name,count(*) from user_extents where segment_name='LIUSHENG_HASH' group by partition_name;
PARTITION_NAME COUNT(*)
------------------------------ ----------
SYS_P27 3
SYS_P26 3
SYS_P22 2
SYS_P28 3
SYS_P29 2
SYS_P21 2
SYS_P23 3
SYS_P25 3
SYS_P30 2
SYS_P24 3
select count(*) from liusheng_hash;
COUNT(*)
----------
9860
C.創建list分區,一般用於數據可枚舉,有限個值,可以考慮列表分區,例如國家名字,按州來分區
創建list分區表,我們按國家來分別存放在不同的州,每個州是一個分區
create table liusheng_list
(city_id NUMBER(5),
city_name VARCHAR2(30),
city_state VARCHAR2(20),
city_amount NUMBER(10)
)
partition by list (city_name)
(
partition asia VALUES('china','japan'),
partition europe VALUES ('germany','italy'),
partition africa VALUES('libya','brazil'),
partition other VALUES(DEFAULT) --默認分區
);
插入數據
insert into liusheng_list values(1,'china','asia',100);
insert into liusheng_list values(2,'germany','europe',101);
insert into liusheng_list values(3,'libya','africa',102);
insert into liusheng_list values(4,'liusheng_city','other',103);
查看數據
LS@LEO> select * from liusheng_list;
CITY_ID COUNTRY_NAME STATE CITY_AMOUNT
---------- ------------------------------ -------------------- -----------
1 china asia 100
2 germany europe 101
3 libya africa 102
4 liusheng_city other 103
補充:分區之優勢
分區技術實質可以把數據分攤到不同的物理位置,增加I/O負載,提高檢索效率。
可用性:分區表可以跨越表空間,而普通表則不然,好處就是如果表的一個分區損壞,其他分區不會受到影響我們只需要修復損壞的分區即可
=============================================
四、sqlloader 的參數
errors -- 允許的錯誤記錄數,可以用他來控制一條記錄都不能錯
rows -- 多少條記錄提交一次,默認爲 64 skip -- 跳過的行數,比如導出的數據文件前面幾行是表頭或其他描述
Fields terminated by ‘|’ -- 數據中每行記錄用 "," 分隔
Optionally enclosed by ‘“’ -- 數據中每個字段用 '"' 框起,比如字段中有 "," 分隔符時
======================================