mysql中bit_count和bit_or使用

在看參考手冊的時候看到個案例
3.6.8 Calculating Visits Per Day

create table t1(year YEAR(4), month INT(2) UNSIGNED ZEROFILL, day INT(2) UNSIGNED ZEROFILL);
insert into t1 values(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),(2000,2,23),(2000,2,23);
select * from t1;
QQ圖片20180726203424.png

首先要說明以下幾個函數(shù)
bit_count:
就是計算二進制里有多少個1
10的二進制是1010
bit_count(10) = 2
100的二進制是1100100
bit_count(123) = 3

bit_or:
按位或,就是如果兩邊一個位置上存在1,那這個位置就為1
拿上面10和100舉例
10 | 100 轉換為二進制就是 1010|1100100
1010
1100100


1101110

1<<day:
向左位移,向左位移幾位,然后用0填補
比如day=2
1<<2 = 100
day=4
1<<4 = 10000

回到主題,現(xiàn)在要計算出圖中每天的訪問量,可以看到day列中是存在重復記錄的,所以要去除,一般思路應該會寫出以下SQL:

mysql> select year,month,count(0) from (select year,month,count(day) from t1 group by year,month,day) as tmp group by year,month;

這個的確可以得到正確值,但是官方參考文檔里使用了更巧妙的算法

select year,month,bit_count(bit_or(1<<day)) from t1 group by year,month;

為了演示,現(xiàn)在將day設定為1,2,2,3好了,那就等于
bit_or(1<<1, 1<<2, 1<<2, 1<<3)
10 | 100 | 100 | 1000 => 110 | 100 | 1000 => 110 | 1000 => 1110
當110 | 100的時候,相同的值就不會發(fā)生變化,所以最后bit_count的結果就為3

插入2w條數(shù)據(jù)后,看下執(zhí)行計劃,第一種SQL執(zhí)行兩遍全表掃描

為了明確看到查詢性能,我們啟用profiling并關閉query cache:

SET profiling = 1;
SET query_cache_type = 0;
SET GLOBAL query_cache_size = 0;
image.png
image.png
image.png
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容