數字輔助表是乙個包含從 1 到 n 的 n 個整數的簡單表,n 通常很大。因為數字輔助表是乙個非常強大的工具,可能經常需要在解決方案中用到它,所以建議建立乙個持久的數字輔助表,並根據需要填充一定資料量的值 --《mysql技術內幕:sql程式設計》
建立數字輔助表:create table `nums` (
`a` int(10) unsigned not null,
primary key (`a`)
) engine=innodb;
建立儲存過程:delimiter ;;
create procedure `pcreatenums`(cnt int unsigned)
begin
declare s int unsigned default 1;
truncate table nums;
while s <= cnt do
begin
insert into nums select s;
set s = s+1;
end;
end while;
end;;
delimiter ;
這個方法沒有任何的問題,只是執行效率不高。例如要插入 100,000 行的資料,至少需要 1 分鐘的時間(具體時間還要看各自的裝置效能),如下:mysql> call pcreatenums(200000);
query ok, 1 row affected (40.83 sec)
這個方法的主要開銷在於 insert 語句被執行了 100,000 次。我們可以通過下面這個方法來快速建立數字輔助表。delimiter ;;
create procedure `pfastcreatenums`(cnt int unsigned)
begin
declare s int unsigned default 1;
truncate table nums;
insert into nums select s;
while s*2 <= cnt do
begin
insert into nums select a+s from nums;
set s = s*2;
end;
end while;
end;;
delimiter ;
在這個儲存過程中,變數 s 儲存插入該錶的行數。該過程先把 1 插入數字輔助表,然後當 s*2 <= cnt 成立時執行迴圈。在每次迭代中,該過程把數字輔助表當前所有行的值加上 s 後再插入數字輔助表中,即先插入 ,然後是 ,,,,以此類推。因此這個儲存過程的執行時間非常之快。要插入 200,000 行資料,情況如下:mysql> call pfastcreatenums(200000);
query ok, 65536 rows affected (0.53 sec)
可以看到執行時間縮短到了1秒鐘,效能提高了 70 多倍。究其原因,是因為實際執行 insert 的次數少了。這裡我們是按照 2 的指數次進行插入的,實際只執行了 17 次插入操作。這個解決方案的唯一缺點是,數字輔助表是按照 2 的指數次進行插入的,因此上述實際的插入行數是 131,072,而不是 200,000 行。查詢一下剛才插入的資料,結果如下:+----------+
| count(*) |
| 131072 |
1 row in set (0.04 sec)
不過這不是乙個很大的問題,因為我們可以在取出資料時使用 <= 來擷取指定的行數,如:select * from nums where a <= 100000;
有了這張輔助表,使用者可以通過它來輔助很多其他應用。例如,在資料倉儲中,通常需要生成某個時間範圍內的時間維度表,這時使用數字輔助表會非常簡單和快捷,示例如下:delimiter ;;
create procedure `pcreatedimtime`(start date, end date)
begin
select date_add(start,interval a-1 day) from nums where a<=datediff(end,start)+1;
end;;
delimiter ;
參考資料
mysql數字輔助表 MySQL中數字輔助表的建立
數字輔助表是乙個只包含從1到n的n個整數的簡單表,n通常非常大 如何建立這樣乙個輔助表 1 我們可以通過下面這個方式建立 mysql create table nums a int unsigned not null primary key engine innodb query ok,0 rows...
mysql 日期輔助表
1 建立乙個num表,用來儲存數字0 9create table num i int 2 在num表中生成0 9insert into num i values 0 1 2 3 4 5 6 7 8 9 3 生成乙個儲存日期的表,datalist是欄位名 create table ifnot exis...
數字輔助表
set nocount on if object id dbo.nums is not null drop table dbo.nums gocreate table dbo.nums n int not null primary key declare max as int,rc as int s...