當前位置:首頁 » 編程語言 » sql如何減小體積
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

sql如何減小體積

發布時間: 2022-05-08 18:36:01

sql lite如何減小體積

1.建表優化
SQLite的資料庫本質文件讀寫操作,頻繁操作打開和關閉是很耗時和浪費資源的;

優化方法事務機制:
這里要注意一點:事務的開啟是要鎖定DB的,其他對DB的寫入操作都是無法成功的。
db.beginTransaction(); //手動設置開始事務
try {
//這里寫你數據操作
db.setTransactionSuccessful();
//設置事務處理成功,不設置會自動回滾不提交
} catch (Exception e) {
} finaly {
db.endTransaction(); //提交
}

項目中不會把項目上萬條數據存SQL里的,盡管android有SQLite。
那樣處理起來非常慢,而且程序經常出現ANR。

打個比方:有200個城市,每個城市500條城市信息,你怎麼創建表?

A:我創建一張表存10000條數據。
B:200張表,每張存500條數據。
C:我創建兩張表,
一張存city,其實這張表只有1條數據;
Id(編號),
Version(這200個城市更新版本用)
CityDate(200個城市xml格式字元串數據)。

另一張表存城市信息表:200條數據,每個城市一條數據
id(CityDate解析出城市對象對應的id)
Version(這500條城市信息更新版本用)
CityMessage(500條城市信息xml格式字元串數據)。

首先你給用戶展示200城市(你只取了一條數據 200個城市xml格式字元串數據進行解析)
用戶點擊一個城市你顯示500條記錄(通過城市解析ID,取出城市信息表中對應500數據xml格式字元串數據進行解析)

這樣做的好處:
(1)統一數據介面,無論你從網路上直接去數據,還是讀本地緩存統一數據介面,xml
(2)數據進行排序,內存操作要快一些;
(3)其實這和自己寫文件沒什麼區別,為什麼還要用資料庫那,這么做有利於程序版本更新升級數據
維護!

2.其他技巧

1) 相對於封裝過的ContentProvider而言,使用原始SQL語句執行效率高,比如使用方法rawQuery、execSQL的執行效率比較高。

2) 對於需要一次性修改多個數據時,可以考慮使用SQLite的事務方式批量處理,我們定義SQLiteDatabase db對象,執行的順序為

db.beginTransaction();
//這里處理數據添加,刪除或修改的SQL語句
db.setTransactionSuccessful(); //這里設置處理成功
db.endTransaction(); //這句很重要,告訴資料庫處理完成了,這時SQLite的底層會執行具體的數據操作。

3) 打好SQL語句的基礎,對於查詢,以及分配表的結構都十分重要

3.
一、影響查詢性能的因素:

1. 對表中行的檢索數目,越小越好
2. 排序與否。
3. 是否要對一個索引。
4. 查詢語句的形式

二、幾個查詢優化的轉換

1. 對於單個表的單個列而言,如果都有形如T.C=expr這樣的子句,並且都是用OR操作符連接起來,形如: x = expr1 OR expr2 = x OR x = expr3 此時由於對於OR,在SQLite中不能利用索引來優化,所以可以將它轉換成帶有IN操作符的子句:x IN(expr1,expr2,expr3)這樣就可以用索引進行優化,效果很明顯,但是如果在都沒有索引的情況下OR語句執行效率會稍優於IN語句的效率。

2. 如果一個子句的操作符是BETWEEN,在SQLite中同樣不能用索引進行優化,所以也要進行相應的等價轉換: 如:a BETWEEN b AND c可以轉換成:(a BETWEEN b AND c) AND (a>=b) AND (a<=c)。 在上面這個子句中, (a>=b) AND (a<=c)將被設為dynamic且是(a BETWEEN b AND c)的子句,那麼如果BETWEEN語句已經編碼,那麼子句就忽略不計,如果存在可利用的index使得子句已經滿足條件,那麼父句則被忽略。

3. 如果一個單元的操作符是LIKE,那麼將做下面的轉換:x LIKE 『abc%』,轉換成:x>=『abc』 AND x<『abd』。因為在SQLite中的LIKE是不能用索引進行優化的,所以如果存在索引的話,則轉換後和不轉換相差很遠,因為對LIKE不起作用,但如果不存在索引,那麼LIKE在效率方面也還是比不上轉換後的效率的。

三、 幾種查詢語句的處理(復合查詢)

1.查詢語句為:<SelectA> <operator> <selectB> ORDER BY <orderbylist> ORDER BY 執行方法: is one of UNION ALL, UNION, EXCEPT, or INTERSECT. 這個語句的執行過程是先將selectA和selectB執行並且排序,再對兩個結果掃描處理,對上面四種操作是不同的,將執行過程分成七個子過程:

outA: 將selectA的結果的一行放到最終結果集中

outB: 將selectA的結果的一行放到最終結果集中(只有UNION操作和UNION ALL操作,其它操作都不放入最終結果集中)

AltB: 當selectA的當前記錄小於selectB的當前記錄
AeqB: 當selectA的當前記錄等於selectB的當前記錄
AgtB: 當selectA的當前記錄大於selectB的當前記錄
EofA: 當selectA的結果遍歷完
EofB: 當selectB的結果遍歷完

四、子查詢扁平化

例子:SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5

對這個SQL語句的執行一般默認的方法就是先執行內查詢,把結果放到一個臨時表中,再對這個表進行外部查詢,這就要對數據處理兩次,另外這個臨時表沒有索引,所以對外部查詢就不能進行優化了,如果對上面的SQL進行處理後可以得到如下SQL語句:SELECT x+y AS a FROM t1 WHERE z<100 AND a>5,這個結果顯然和上面的一樣,但此時只需要對數據進行查詢一次就夠了,另外如果在表t1上有索引的話就避免了遍歷整個表。

運用flatten方法優化SQL的條件:

1.子查詢和外查詢沒有都用集函數
2.子查詢沒有用集函數或者外查詢不是個表的連接
3.子查詢不是一個左外連接的右操作數
4.子查詢沒有用DISTINCT或者外查詢不是個表的連接
5.子查詢沒有用DISTINCT或者外查詢沒有用集函數
6.子查詢沒有用集函數或者外查詢沒有用關鍵字DISTINCT
7.子查詢有一個FROM語句
8.子查詢沒有用LIMIT或者外查詢不是表的連接
9.子查詢沒有用LIMIT或者外查詢沒有用集函數
10.子查詢沒有用集函數或者外查詢沒用LIMIT
11.子查詢和外查詢不是同時是ORDER BY子句
12.子查詢和外查詢沒有都用LIMIT
13.子查詢沒有用OFFSET
14.外查詢不是一個復合查詢的一部分或者子查詢沒有同時用關鍵字ORDER BY和LIMIT
15.外查詢沒有用集函數子查詢不包含ORDER BY
16.復合子查詢的扁平化:子查詢不是一個復合查詢,或者他是一個UNION ALL復合查詢,但他是都由若干個非集函數的查詢構成,他的父查詢不是一個復合查詢的子查詢,也沒有用集函數或者是DISTINCT查詢,並且在FROM語句中沒有其它的表或者子查詢,父查詢和子查詢可能會包含WHERE語句,這些都會受到上面11、12、13條件的限制。

SELECT a+1 FROM (
SELECT x FROM tab
UNION ALL
SELECT y FROM tab
UNION ALL
SELECT abs(z*2) FROM tab2
) WHERE a!=5 ORDER BY 1

轉換為:

SELECT x+1 FROM tab WHERE x+1!=5

UNION ALL
SELECT y+1 FROM tab WHERE y+1!=5
UNION ALL
SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
ORDER BY 1

五、連接查詢
在返回查詢結果之前,相關表的每行必須都已經連接起來,在SQLite中,這是用嵌套循環實現的,在早期版本中,最左邊的是最外層循環,最右邊的是最內層循環,連接兩個或者更多的表時,如果有索引則放到內層循環中,也就是放到FROM最後面,因為對於前面選中的每行,找後面與之對應的行時,如果有索引則會很快,如果沒有則要遍歷整個表,這樣效率就很低,但在新版本中,這個優化已經實現。

優化的方法如下:
對要查詢的每個表,統計這個表上的索引信息,首先將代價賦值為SQLITE_BIG_DBL(一個系統已經定義的常量):

1、如果沒有索引,則找有沒有在這個表上對rowid的查詢條件:

如果有Rowid=EXPR,如果有的話則返回對這個表代價估計,代價計為零,查詢得到的記錄數為1,並完成對這個表的代價估計。
如果沒有Rowid=EXPR 但有rowid IN (...),而IN是一個列表,那麼記錄返回記錄數為IN列表中元素的個數,估計代價為NlogN,
如果IN不是一個列表而是一個子查詢結果,那麼由於具體這個子查詢不能確定,所以只能估計一個值,返回記錄數為100,代價為200。

如果對rowid是范圍的查詢,那麼就估計所有符合條件的記錄是總記錄的三分之一,總記錄估計為1000000,並且估計代價也為記錄數。
如果這個查詢還要求排序,則再另外加上排序的代價NlogN
如果此時得到的代價小於總代價,那麼就更新總代價,否則不更新。

2、如果WHERE子句中存在OR操作符,那麼要把這些OR連接的所有子句分開再進行分析。

如果有子句是由AND連接符構成,那麼再把由AND連接的子句再分別分析。
如果連接的子句的形式是X<op><expr>,那麼就再分析這個子句。
接下來就是把整個對OR操作的總代價計算出來。
如果這個查詢要求排序,則再在上面總代價上再乘上排序代價NlogN
如果此時得到的代價小於總代價,那麼就更新總代價,否則不更新。

3、如果有索引,則統計每個表的索引信息,對於每個索引:

先找到這個索引對應的列號,再找到對應的能用到(操作符必須為=或者是IN(…))這個索引的WHERE子句,如果沒有找到,則退出對每個索引的循環,如果找到,則判斷這個子句的操作符是什麼,如果是=,那麼沒有附加的代價,如果是IN(sub-select),那麼估計它附加代價inMultiplier為25,如果是IN(list),那麼附加代價就是N(N為list的列數)。

再計算總的代價和總的查詢結果記錄數和代價。
nRow = pProbe->aiRowEst * inMultiplier;/*計算行數*/
cost = nRow * estLog(inMultiplier);/*統計代價*/
如果找不到操作符為=或者是IN(…)的子句,而是范圍的查詢,那麼同樣只好估計查詢結果記錄數為nRow/3,估計代價為cost/3。
同樣,如果此查詢要求排序的話,再在上面的總代價上加上NlogN
如果此時得到的代價小於總代價,那麼就更新總代價,否則不更新。

4、通過上面的優化過程,可以得到對一個表查詢的總代價

再對第二個表進行同樣的操作,這樣如此直到把FROM子句中所有的表都計算出各自的代價,最後取最小的,這將作為嵌套循環的最內層,依次可以得到整個嵌套循環的嵌套順序,此時正是最優的,達到了優化的目的。

5、所以循環的嵌套順序不一定是與FROM子句中的順序一致,因為在執行過程中會用索引優化來重新排列順序。

六、索引

在SQLite中,有以下幾種索引:
1) 單列索引
2) 多列索引
3) 唯一性索引
4) 對於聲明為:INTEGER PRIMARY KEY的主鍵來說,這列會按默認方式排序,所以雖然在數據字典中沒有對它生成索引,但它的功能就像個索引。所以如果在這個主鍵上在單獨建立索引的話,這樣既浪費空間也沒有任何好處。

運用索引的注意事項:
1) 對於一個很小的表來說沒必要建立索引
2) 在一個表上如果經常做的是插入更新操作,那麼就要節制使用索引
3) 也不要在一個表上建立太多的索引,如果建立太多的話那麼在查詢的時候SQLite可能不會選擇最好的來執行查詢,一個解決辦法就是建立聚蔟索引。

索引的運用時機:

1) 操作符:=、>、<、IN等
2) 操作符BETWEEN、LIKE、OR不能用索引,
如BETWEEN:SELECT * FROM mytable WHERE myfield BETWEEN 10 and 20;
這時就應該將其轉換成:
SELECT * FROM mytable WHERE myfield >= 10 AND myfield <= 20;
此時如果在myfield上有索引的話就可以用了,大大提高速度
再如LIKE:SELECT * FROM mytable WHERE myfield LIKE 'sql%';
此時應該將它轉換成:
SELECT * FROM mytable WHERE myfield >= 'sql' AND myfield < 'sqm';
此時如果在myfield上有索引的話就可以用了,大大提高速度
再如OR:SELECT * FROM mytable WHERE myfield = 'abc' OR myfield = 'xyz';
此時應該將它轉換成:
SELECT * FROM mytable WHERE myfield IN ('abc', 'xyz');
此時如果在myfield上有索引的話就可以用了,大大提高速度
3) 有些時候索引都是不能用的,這時就應該遍歷全表(程序演示)

② MSSQL\Data 下的文件為什麼會很大該如何處理

很大是因為數據記錄很多。
資料庫可以通過優化減小體積,但是減小的大小很有限。
因此,一般沒必要處理,因為那些本來就是你需要的數據。除非你不要了。

③ SQL資料庫太大怎麼辦

--1.日常要做資料庫壓縮

--壓縮日誌及資料庫文件大小

/*--特別注意
請按步驟進行,未進行前面的步驟,請不要做後面的步驟
否則可能損壞你的資料庫.
--*/

1.清空日誌
DUMP TRANSACTION 庫名 WITH NO_LOG

2.截斷事務日誌:
BACKUP LOG 資料庫名 WITH NO_LOG

3.收縮資料庫文件(如果不壓縮,資料庫的文件不會減小
企業管理器--右鍵你要壓縮的資料庫--所有任務--收縮資料庫--收縮文件
--選擇日誌文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了
--選擇數據文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了

也可以用SQL語句來完成
--收縮資料庫
DBCC SHRINKDATABASE(客戶資料)

--收縮指定數據文件,1是文件號,可以通過這個語句查詢到:select * from sysfiles
DBCC SHRINKFILE(1)

4.為了最大化的縮小日誌文件(如果是sql 7.0,這步只能在查詢分析器中進行)
a.分離資料庫:
企業管理器--伺服器--資料庫--右鍵--分離資料庫

b.在我的電腦中刪除LOG文件

c.附加資料庫:
企業管理器--伺服器--資料庫--右鍵--附加資料庫

此法將生成新的LOG,大小隻有500多K

或用代碼:
下面的示例分離 pubs,然後將 pubs 中的一個文件附加到當前伺服器。

a.分離
EXEC sp_detach_db @dbname = 'pubs'

b.刪除日誌文件

c.再附加
EXEC sp_attach_single_file_db @dbname = 'pubs',
@physname = 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs.mdf'

5.為了以後能自動收縮,做如下設置:
企業管理器--伺服器--右鍵資料庫--屬性--選項--選擇"自動收縮"

--SQL語句設置方式:
EXEC sp_dboption '資料庫名', 'autoshrink', 'TRUE'

6.如果想以後不讓它日誌增長得太大
企業管理器--伺服器--右鍵資料庫--屬性--事務日誌
--將文件增長限制為xM(x是你允許的最大數據文件大小)

--SQL語句的設置方式:
alter database 資料庫名 modify file(name=邏輯文件名,maxsize=20)

④ mssql資料庫太大怎麼壓縮

資料庫在使用一段時間後,時常會出現因數據刪除而造成資料庫中空閑空間太多的情況,這時就需要減少分配給資料庫文件和事務日誌文件的磁碟空間,以免浪費磁碟空間。當資料庫中沒有數據時,可以修改資料庫文件屬性直接改變其佔用空間,但當資料庫中有數據時,這樣做會破壞資料庫中的數據,因此需要使用壓縮的方式來縮減資料庫空間。可以在資料庫屬性選項中選擇「Auto shrink」選項,讓系統自動壓縮資料庫,也可以用人工的方法來壓縮。人工壓縮資料庫有以下兩種方式:

1、用Enterprise Manager 壓縮資料庫
在Enterprise Manager 中在所要壓縮的資料庫上單擊右鍵,從快捷菜單中的「所有任務(All Tasks)」中選擇「Shrink Database(壓縮資料庫)」選項
、用Transact-SQL 命令壓縮資料庫
可以使用DBCC SHRINKDATABASE 和DBCC SHRINKFILE 命令來壓縮資料庫。其中DBCC SHRINKDATABASE 命令對資料庫進行壓縮,DBCC SHRINKFILE 命令對資料庫中指定的文件進行壓縮。

(1) DBCC SHRINKDATABASE
DBCC SHRINKDATABASE 命令語法如下:
DBCC SHRINKDATABASE (database_name [, target_percent]
[, {NOTRUNCATE | TRUNCATEONLY}] )
各參數說明如下:

target_percent 指定將資料庫壓縮後,未使用的空間占資料庫大小的百分之幾。如果指定的百分比過大,超過了壓縮前未使用空間所佔的比例,則資料庫不會被壓縮。並且壓縮後的資料庫不能比資料庫初始設定的容量小。
NOTRUECATE
將資料庫縮減後剩餘的空間保留在資料庫,中不返還給操作系統。如果不選擇此選項,則剩餘的空間返還給操作系統。
TRUNCATEONLY
將資料庫縮減後剩餘的空間返還給操作系統。使用此命令時SQL Server 將文件縮減到最後一個文件分配,區域但不移動任何數據文件。選擇此項後,target_percent 選項就無效了。
壓縮資料庫mytest 的未使用空間為資料庫大小的20%。
dbcc shrinkdatabase (mytest, 20)
運行結果如下:
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

(2) DBCC SHRINKFILE
DBCC SHRINKFILE 命令壓縮當前資料庫中的文件。其語法如下:
DBCC SHRINKFILE ( {file_name | file_id }
{ [, target_size] |
[, {EMPTYFILE | NOTRUNCATE | TRUNCATEONLY}] } )
各參數說明如下:

file_id
指定要壓縮的文件的鑒別號(Identification number, 即ID)。文件的ID 號可以通過 FILE_ID()函數或如本章前面所講述的Sp_helpdb 系統存儲過程來得到。
target_size
指定文件壓縮後的大小。以MB 為單位。如果不指定此選項,SQL Server 就會盡最大可能地縮減文件。
EMPTYFILE
指明此文件不再使用,將移動所有在此文件中的數據到同一文件組中的其它文件中去。執行帶此參數的命令後,此文件就可以用ALTER DATABASE 命令來刪除了。
其餘參數NOTRUNCATE 和TRUNCATEONLY 與DBCC SHRINKDATABASE 命令中的含義相同。
例6-15: 壓縮資料庫mydb 中的資料庫文件mydb_data2 的大小到1MB。 use mydb dbcc shrinkfile (mydb_data2, 1)

⑤ SQL資料庫文件太大怎麼處理

如果是MSSQL在任務里選資料庫收縮,可以縮小很多。
不然只能把數據導出來減小資料庫了。

⑥ SQL 資料庫收縮問題

SQL資料庫收縮一種是自動收縮:在資料庫屬性選項里,將自動收縮設置為True
另外一種是手動收縮:調節最大可用空間到合適的值根據具體的需求進行設置,一般設置為40%為宜。

⑦ sql資料庫日誌文件過大怎麼辦

經過幾個小時的測試,最有用的方法如下:

  1. 停止資料庫MSSQL實
  2. 復制資料庫目標庫文件('***.mdf')重新命名
  3. 執行如下SQL語句,注意修改正確的庫名
  4. EXECsp_attach_single_file_db@dbname='庫名',
    @physname='D:_50.MSSQLSERVERMSSQLDATA庫名.mdf'
  5. 資料庫屬性/文件/限制文件增長
  6. 資料庫屬性/選項/設置資料庫收縮為[自動收縮]

⑧ 如何減肥SQL資料庫的容量

/*--特別注意 請按步驟進行,未進行前面的步驟,請不要做後面的步驟 否則可能損壞你的資料庫. 一般不建議做第4,6兩步 第4步不安全,有可能損壞資料庫或丟失數據 第6步如果日誌達到上限,則以後的資料庫處理會失敗,在清理日誌後才能恢復. --*/ --下面的所有庫名都指你要處理的資料庫的庫名 1.清空日誌 DUMP TRANSACTION 庫名 WITH NO_LOG 2.截斷事務日誌: BACKUP LOG 庫名 WITH NO_LOG 3.收縮資料庫文件(如果不壓縮,資料庫的文件不會減小 企業管理器--右鍵你要壓縮的資料庫--所有任務--收縮資料庫--收縮文件 --選擇日誌文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了 --選擇數據文件--在收縮方式里選擇收縮至XXM,這里會給出一個允許收縮到的最小M數,直接輸入這個數,確定就可以了 也可以用SQL語句來完成 --收縮資料庫 DBCC SHRINKDATABASE(庫名) --收縮指定數據文件,1是文件號,可以通過這個語句查詢到:select * from sysfiles DBCC SHRINKFILE(1) 4.為了最大化的縮小日誌文件(如果是sql 7.0,這步只能在查詢分析器中進行) a.分離資料庫: 企業管理器--伺服器--資料庫--右鍵--分離資料庫 b.在我的電腦中刪除LOG文件 c.附加資料庫: 企業管理器--伺服器--資料庫--右鍵--附加資料庫 此法將生成新的LOG,大小隻有500多K 或用代碼: 下面的示例分離 pubs,然後將 pubs 中的一個文件附加到當前伺服器。 a.分離 EXEC sp_detach_db @dbname = '庫名' b.刪除日誌文件 c.再附加 EXEC sp_attach_single_file_db @dbname = '庫名', @physname = 'c:\Program Files\Microsoft SQL Server\MSSQL\Data\庫名.mdf' 5.為了以後能自動收縮,做如下設置: 企業管理器--伺服器--右鍵資料庫--屬性--選項--選擇"自動收縮" --SQL語句設置方式: EXEC sp_dboption '庫名', 'autoshrink', 'TRUE' 6.如果想以後不讓它日誌增長得太大 企業管理器--伺服器--右鍵資料庫--屬性--事務日誌 --將文件增長限制為xM(x是你允許的最大數據文件大小) --SQL語句的設置方式: alter database 庫名 modify file(name=邏輯文件名