1. 程式人生 > >一天一篇mysql之十八:mysql中的limit、between and、in

一天一篇mysql之十八:mysql中的limit、between and、in

limit關鍵字

Limit子句可以被用於強制 SELECT 語句返回指定的記錄數。Limit接受一個或兩個數字引數。引數必須是一個整數常量。如果給定兩個引數,第一個引數指定第一個返回記錄行的偏移量,第二個引數指定返回記錄行的最大數目。

  //初始記錄行的偏移量是 0(而不是 1):
  mysql> SELECT * FROM table LIMIT 5,10; //檢索記錄行6-15

  //為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個引數為 -1:
  mysql> SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last

  //如果只給定一個引數,它表示返回最大的記錄行數目。換句話說,LIMIT n 等價於 LIMIT 0,n:
  mysql> SELECT * FROM table LIMIT 5;     //檢索前 5 個記錄行

Limit的效率高?

  常說的Limit的執行效率高,是對於一種特定條件下來說的:即資料庫的數量很大,但是隻需要查詢一部分資料的情況。
  高效率的原理是:避免全表掃描,提高查詢效率。

  比如:每個使用者的email是唯一的,如果使用者使用email作為使用者名稱登陸的話,就需要查詢出email對應的一條記錄。
  SELECT * FROM t_user WHERE email=?;
  上面的語句實現了查詢email對應的一條使用者資訊,但是由於email這一列沒有加索引,會導致全表掃描,效率會很低。
  SELECT * FROM t_user WHERE email=? LIMIT 1;
  加上LIMIT 1,只要找到了對應的一條記錄,就不會繼續向下掃描了,效率會大大提高。

Limit的效率低?

  在一種情況下,使用limit效率低,那就是:只使用limit來查詢語句,並且偏移量特別大的情況

  做以下實驗:
      語句1:
           select * from table limit 150000,1000;
  語句2:
           select * from table while id>=150000 limit 1000;
  語句1為0.2077秒;語句2為0.0063秒
  兩條語句的時間比是:語句1/語句2=32.968
  
  比較以上的資料時,我們可以發現採用where...limit....效能基本穩定,受偏移量和行數的影響不大,而單純採用limit的話,受偏移量的影響很大,當偏移量大到一定後效能開始大幅下降。不過在資料量不大的情況下,兩者的區別不大。

  所以應當先使用where等查詢語句,配合limit使用,效率才高

  ps:在sql語句中,limt關鍵字是最後才用到的。以下條件的出現順序一般是:where->group by->having-order by->limit
附錄:OFFSET

  為了與 PostgreSQL 相容,MySQL 也支援句法: LIMIT # OFFSET #。
  經常用到在資料庫中查詢中間幾條資料的需求
  比如下面的sql語句:
    ① selete * from testtable limit 2,1;
    ② selete * from testtable limit 2 offset 1;
  注意:
    1.資料庫資料計算是從0開始的
    2.offset X是跳過X個數據,limit Y是選取Y個數據
    3.limit  X,Y  中X表示跳過X個數據,讀取Y個數據
  這兩個都是能完成需要,但是他們之間是有區別的:
    ①是從資料庫中第三條開始查詢,取一條資料,即第三條資料讀取,一二條跳過
    ②是從資料庫中的第二條資料開始查詢兩條資料,即第二條和第三條。

MySQL BETWEEN 用法

BETWEEN 運算子用於 WHERE 表示式中,選取介於兩個值之間的資料範圍。BETWEEN 同 AND 一起搭配使用,語法如下:

WHERE column BETWEEN value1 AND value2
WHERE column NOT BETWEEN value1 AND value2

通常 value1 應該小於 value2。當 BETWEEN 前面加上 NOT 運算子時,表示與 BETWEEN 相反的意思,即選取這個範圍之外的值。

BETWEEN 例項
選取 uid 在 2 到 5 之間的使用者資料:

SELECT * FROM user WHERE uid BETWEEN 2 AND 5

返回查詢結果如下:

20151216160201795.png (639×132)

除了數值型別外,BETWEEN 也支援字串範圍,如下選擇出所有 username 介於 a 至 j 之間的使用者(幷包括單字母k/K):
SELECT * FROM user WHERE username BETWEEN 'a' AND 'k'
字元範圍也支援漢字,但通常來說沒什麼意義。
MySQL BETWEEN 邊界
雖然幾乎所有的資料庫都支援 BETWEEN ... AND 運算子,但不同的資料庫對 BETWEEN ... AND 處理方式是有差異的。在 MySQL 中,BETWEEN 包含了 value1 和 value2 邊界值,如上面選取 uid 在 2 到 5 之間的使用者資料例子。
而有的資料庫則不包含 value1 和 value2 邊界值(類似於 > and <),也有資料庫包含 value1 而不包含 value2(類似於 >= and <)。所以在使用 BETWEEN ... AND 的時候,請檢查你的資料庫是如何處理 BETWEEN 邊界值的。
MySQL BETWEEN 時間日期
BETWEEN AND 常用於檢索時間或日期段內的內容,下面是一些常見的 BETWEEN 時間日期例子:

// int 時間戳格式,查詢 2008-08-08 20:00:00 到 2009-01-01 零點之前的資料
SELECT * FROM table WHERE column_time BETWEEN 1218196800 AND 1230739199
 
// DATE 格式,查詢 2008-08-08 到 2009-01-01 零點之前的資料
SELECT * FROM table WHERE column_time BETWEEN '2008-08-08' AND '2009-01-01'
 
// DATETIME 格式,查詢 2008-08-08 20:00:00 到 2009-01-01 零點之前的資料
SELECT * FROM table WHERE column_time BETWEEN '2008-08-08 20:00:00' AND '2008-12-31 23:59:59'
但對於查詢到當前時間的資料,建議使用 >= 運算子:
// DATETIME 格式,查詢 2008-08-08 20:00:00 到當前時刻的資料
SELECT * FROM table WHERE column_time >= '2008-08-08 20:00:00'

可見,同樣的需求,不同的欄位型別,寫法可能就不一樣。從效率上來講,int 時間戳格式效率最優。
以上 BETWEEN 的各個例子,雖然都是 SELECT 查詢,但 BETWEEN 也可以用於 UPDATE、DELETE 等適用 WHERE 表示式的 SQL 中。
MySQL BETWEEN 資料比較
BETWEEN 還具有資料比較功能,語法如下:

expr BETWEEN min AND max

當 expr 表示式的值大於或等於 min 且小於或等於 max 時, BETWEEN 的返回值為 1 ,否則返回 0 。利用這個功能,可以判斷一個表示式或值否則在某個區間:

// 返回 0
SELECT 1 BETWEEN 2 AND 3
// 返回 1
SELECT 'b' BETWEEN 'a' AND 'c'
// 判斷日期範圍
SELECT 20080808 BETWEEN 20080101 AND 20090101

BETWEEN 與 <、<=、>=、> 等運算子在某些情況下有著類似的功能,但 BETWEEN 運算級別更高且效率上更甚一籌。當然由於 BETWEEN 存在邊界值的問題而不夠靈活,因此不同的情況,採用何種運算子,需要具體對待。

MySQL IN 用法

IN 運算子用於 WHERE 表示式中,以列表項的形式支援多個選擇,語法如下:

WHERE column IN (value1,value2,...)
WHERE column NOT IN (value1,value2,...)

當 IN 前面加上 NOT 運算子時,表示與 IN 相反的意思,即不在這些列表項內選擇。
IN 使用例項
選取 uid 為 2、3、5 的使用者資料:

SELECT * FROM user WHERE uid IN (2,3,5)

返回查詢結果如下:

20151216160410446.png (638×104)

IN 子查詢
更多情況下,IN 列表項的值是不明確的,而可能是通過一個子查詢得到的:
SELECT * FROM article WHERE uid IN(SELECT uid FROM user WHERE status=0)
在這個 SQL 例子裡,我們實現了查出所有狀態為 0 的使用者(可能是被禁止)的所有文章。首先通過一個查詢得到所有所有 status=0 的使用者:

SELECT uid FROM user WHERE status=0

然後將查詢結果作為 IN 的列表項以實現最終的查詢結果,注意在子查詢中返回的結果必須是一個欄位列表項。

IN 運算子補充說明
IN 列表項不僅支援數字,也支援字元甚至時間日期型別等,並且可以將這些不同型別的資料項混合排列而無須跟 column 的型別保持一致:

SELECT * FROM user WHERE uid IN(1,2,'3','c')

一個 IN 只能對一個欄位進行範圍比對,如果要指定更多欄位,可以使用 AND 或 OR 邏輯運算子:
SELECT * FROM user WHERE uid IN(1,2) OR username IN('admin','5idev')
使用 AND 或 OR 邏輯運算子後,IN 還可以和其他如 LIKE、>=、= 等運算子一起使用。
關於 IN 運算子的效率問題
如果 IN 的列表項是確定的,那麼可以用多個 OR 來代替:

SELECT * FROM user WHERE uid IN (2,3,5)
// 等效為:
SELECT * FROM user WHERE (uid=2 OR aid=3 OR aid=5)

一般認為,如果是對索引欄位進行操作,使用 OR 效率高於 IN,但對於列表項不確定的時候(如需要子查詢得到結果),就必須使用 IN 運算子。另外,對於子查詢表資料小於主查詢的時候,也是適用 IN 運算子的。

BETWEEN 和in之間

在MySQL中經常會有朋友問關於大於小於,IN,OR,BETWEEN,哪個效能更好?

我想有很多朋友會用它們但確實不知道大於小於,IN,OR,BETWEEN效能哪個更好吧,下面總結一下關於大於小於,IN,OR,BETWEEN效能。

這裡的查詢條件有四種:>=<=betweenorin

這裡id列是索引列,如果不是的話,三個查詢都是全表掃描,效能差距應該不大。

in走全表是分情況的,上面的解答只是憑記憶大概說了一下,樓下小夥伴比較認真,這裡就再解釋一下,這個不是個數而應該是個比例,大概25%-35%左右,你要再問到底多少不好意思水平有限不讀原始碼沒辦法確認。然後這個30左右的比例也並不是說一定走全表掃描,因為mysql還有一個索引掃描,就是說如果select的內容在你的索引裡面就能找到的話當然不會去掃全表了,比如下面的例子中select id from ttt where id in (..);和select * from ttt where id in (...);前面這個肯定是走主鍵掃描,即使你in了所有id值他也是走主鍵,而後面的情況就是這種百分比的情況了,具體看下面示例,歡迎指正^_^
額,然後還想說一下between的情況,為什麼好是因為除了索引段上連續存取減少解析以外,還有一個情況就是在磁碟定址檢索資料的時候,會預設讀取第一次取值附近的部分資料(有這麼一個概率演算法說的是當一個數據被檢索到的時候,他附近的資料也很大概率會被用到)所以就有了這麼一個一次性取出冗餘資料避免多次定址的情況,這時候使用between的連續取值就正適用了

相關推薦

天一mysqlmysqllimitbetween andin

limit關鍵字 Limit子句可以被用於強制 SELECT 語句返回指定的記錄數。Limit接受一個或兩個數字引數。引數必須是一個整數常量。如果給定兩個引數,第一個引數指定第一個返回記錄行的偏移量,第二個引數指定返回記錄行的最大數目。   //初始記錄行的偏移量是 0(

【Java並發編程】第五volatile意外問題的正確分析解答(含代碼)

深入 規則 rup lis con method 執行 change .text 轉載請註明出處:http://blog.csdn.net/ns_code/article/details/17382679 在《Java並發編程學習筆記之五:volatile變量修

設計模式橋接模式(Bridge)

ora 它的 pla sin string src ams down ng- 橋接模式: 將抽象部分和它的實現部分相分離開來,以使它們能夠單獨地變化。 UML圖: 主要包含: Abstraction:定義了抽象部分的接口。操作一個實現部分對

MYSQL進階學習筆記MySQL備份和還原!(視頻序號進階_37)

back 系統 結構 生產 下載地址 family 需要 絕對路徑 isa 知識點十九:MySQL的備份的還原(38)   一、mysql的備份       1、通過使用mysqldump的命令備份         使用mysqldump命令備份,mysqldump命令將數

skyfans每天一個Liunx命令系列userdel

今天我們繼續來學習USER INFORMATION AND MANAGEMENT(使用者資訊和管理),今天學習的是什麼命令呢,那就是userdel(刪除使用者) 注意:本章內容由於涉及到刪除內容,請在實驗中謹慎操作,切記不可在實際生產環境中執行,否則出現一切後果自負!!!!! Rea

Echarts學習tooltip提示框

tooltip ={ //提示框元件 trigger: 'item',

算法系列用天文方法計算二四節氣(上)

        二十四節氣在中國古代曆法中扮演著非常重要的角色,本文將介紹二十四節氣的基本知識,以及如何使用VSOP82/87行星執行理論計算二十四節氣發生的準確時間。        中國古代曆法都是以月亮執行規律為主,嚴格按照朔望月長度定義月,但是由於朔望月長度和地球迴歸年

kubernetes系列使用helm安裝istio

一、前言 istio是Kubernetes平臺微服務管理的框架標準,是Service Mesh在Kubernetes平臺的標準實現。相比於其它的微服務框架,istio提供非程式碼介入的框架機制,使用sidecar機制將微服務的服務面和管理面連線起來,而且使用的sidecar

MySQL05---DQL單表查詢(指定多條件between..andlike萬用字元空值limit去重合並查詢)

一、查詢指定欄位 1. 查詢所有欄位 select  *  from  表名; 2.查詢指定欄位 select  欄位1,欄位2...   from  表名; 二、條件查詢 概念:條件查詢可通過wher

【轉】【修真院“善良”系列】WEB程序員從零開始到就業的全資料V1.0——只看這就夠了!

absolute feed 自己 session rem 好的 ans 一個 css樣式 這是兩年以來,修真院收集整理的學習資料順序。以CSS15個任務,JS15個任務為基礎,分別依據要完成任務的不同的技能點,我們整理出來了這麽一篇在學習的時候需要看到的資料。這是Versi

敏捷開發千零問系列計劃撲克就是打不出個結果怎麼辦?

本文是敏捷開發一千零一問的第三十八篇。(欄目總目錄)問題:一個簡單的問題,計劃撲克就是打不出個結果,各持己見怎麼辦?也就是少數人無法說服大家,或者說根本無人去聽回答:計劃撲克的結束條件”近似一致“是個很有趣的標準,其實要回答”什麼時候停止打撲克“,就要先解決”為什麼要打撲克“

Nginx詳解Nginx深度學習Rewrite規則

src 開發 gin page return reload 技術 code 效果 Rewrite規則可以實現對url的重寫,以及重定向 作用場景: 1、URL訪問跳轉,支持開發設計,如頁面跳轉,兼容性支持,展示效果等 2、SEO優化 3、維護:後臺維護、流量轉

Mysql學習JDBC連接數據庫DriverManager方法

url state 種類 delet rom 條件 管理系 ont into JDBC連接數據庫 ?創建一個以JDBC連接數據庫的程序,包括7個步驟: 1、載入JDBC驅動程序: 在連接數據庫之前。首先要載入想要連接的數據庫的驅動到JVM

Android實戰技巧Handler使用可能引發的內存泄漏

sha 指向 ons har 引用 destroy 對象 from weak 問題描寫敘述 曾幾何時,我們用原來的辦法使用Handler時會有以下一段溫馨的提示: This Handler class should be static or le

Java並發編程系列CompletionService

xtend cts edate strong ext [] com 喚醒 render CompletionService簡介 CompletionService與ExecutorService類似都可以用來執行線程池的任務,ExecutorService繼承了Execut

步步走>> 設計模式Memento-備忘錄

package com.test.DPs.XingWei.Memento; /** * 行為型:Memento-備忘錄 外觀:作用面為 物件 */ class Original{ private String value; public String getValue(){ ret

敏捷開發千零問系列敏捷開發加班嗎?

這是敏捷開發一千零一問系列的第十四篇。(在這裡提問,之一,之二,之三,問題總目錄)正逢週末,又是愚人節,群中有人正在加班,想起上次培訓中間休息的時候,討論起這個“敏捷開發加班嗎”的問題,雖然後來沒有作為課後投票入選,但這裡也完整回答一下。問題敏捷開發加班嗎?樓下有人問到“敏捷

【Java安全技術探索路系列Java可擴充套件安全架構】JAAS(JAAS架構介紹

【Java安全技術探索之路系列:Java可擴充套件安全架構】章節目錄 JAAS,即Java認證和授權服務。 認證是通過驗證使用者或裝置的身份來判斷真實性和可信賴性的過程。 授權是根據提出請求的身份被授予的許可權來提供訪問資源或執行功能的許可權。

天一部落格----玩轉設計模式策略模式

核心思想 策略模式:分別封裝行為介面,實現演算法族;超類裡放行為介面物件,在子類裡面具體設定行為物件。 原則是就是:分離變化部分 ,封裝介面,基於介面程式設計的各種功能。 此設計模式讓行為演算法的變化獨立於演算法的使用者。 定義duck的抽象類 定義duck的叫聲,飛

性能測試二環境部署Dubbo部署

密碼 pro 項目部 3.4 工作 zookeeper aps war 保存 Zookeeper部署 ZooKeeper是一個分布式的,開放源碼的分布式應用程序協調服務,是Google的Chubby一個開源的實現,是Hadoop和Hbase的重要組件。它是一個為分布式應用提