最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL STORED 生成列(Generated Column) 的使用小結(jié)

 更新時(shí)間:2026年02月11日 09:47:30   作者:Knight_AL  
MySQL 8中的生成列可以解決帶函數(shù)判斷的SQL導(dǎo)致的索引無(wú)法使用和性能問題,生成列分為VIRTUAL和STORED,其中STORED列會(huì)在插入時(shí)計(jì)算并存儲(chǔ)在磁盤上,可以建索引,非常適合用于復(fù)雜的SQL優(yōu)化,下面就一起來(lái)了解一下

在 MySQL 8 中,如果你經(jīng)常寫帶函數(shù)判斷的 SQL,例如:

WHERE WEEKDAY(creatime) < 5

你會(huì)發(fā)現(xiàn):

  • 索引無(wú)法使用
  • 執(zhí)行計(jì)劃 type = ALL
  • 大表查詢慢得像蝸牛

常見的數(shù)據(jù)計(jì)算,比如“是否工作日、是否有效”、“金額是否超過閾值”、“是否逾期”等,都容易寫成函數(shù)形式,導(dǎo)致索引無(wú)法命中。

在高并發(fā)、大數(shù)據(jù)量的場(chǎng)景下,這種寫法會(huì)拖垮整個(gè)系統(tǒng)

解決辦法是什么?

?? MySQL 生成列(Generated Column)+ STORED(存儲(chǔ)列) + 索引

一、什么是生成列(Generated Column)

MySQL 的生成列有兩種:

類型特點(diǎn)
VIRTUAL 虛擬列不存儲(chǔ),查詢時(shí)現(xiàn)算
STORED 存儲(chǔ)列算完真實(shí)寫入磁盤,可建索引

生成列的語(yǔ)法:

column_name data_type
GENERATED ALWAYS AS (表達(dá)式)
[VIRTUAL | STORED]

例如,根據(jù) creatime 自動(dòng)計(jì)算是否工作日:

is_workday TINYINT
GENERATED ALWAYS AS (
    CASE WHEN WEEKDAY(creatime) < 5 THEN 1 ELSE 0 END
) STORED

二、STORED 與普通字段有什么區(qū)別?

很多人不清楚為什么“用 STORED 很香”,下面用一個(gè)表格秒懂??

對(duì)比項(xiàng)普通字段STORED 生成列
值由誰(shuí)計(jì)算?開發(fā)者自己寫入MySQL 根據(jù)表達(dá)式自動(dòng)算
更新時(shí)是否要維護(hù)?要自己維護(hù)creatime 改,自動(dòng)重算
能否防止臟數(shù)據(jù)?容易寫錯(cuò)、漏改保證永遠(yuǎn)正確
能否建索引?可以可以(而且非常常用)
查詢時(shí)需不需要重新計(jì)算?不需要不需要
寫入性能一般插入時(shí)計(jì)算一次
典型場(chǎng)景普通字段業(yè)務(wù)派生字段(是否周末、是否逾期、金額區(qū)間等)

一句話總結(jié):

STORED = 自動(dòng)計(jì)算的普通字段,可建索引,是 SQL 優(yōu)化神器。

三、為什么 STORED 列可以讓 SQL 飛起來(lái)?

來(lái)看經(jīng)典錯(cuò)誤寫法:

WHERE WEEKDAY(creatime) < 5

你對(duì) creatime 做了函數(shù):

  • creatime 索引用不了
  • 強(qiáng)制全表掃
  • 大數(shù)據(jù)量直接炸

而 STORED 生成列寫法:

WHERE is_workday = 1

它是普通字段:

  • 可以建索引
  • 非常高效
  • 查詢極快

MySQL 查詢優(yōu)化器最喜歡:

字段 = 常量
字段 BETWEEN 區(qū)間
字段 IN (...)

生成列完美契合這一點(diǎn)。

四、一個(gè)醫(yī)院真實(shí)業(yè)務(wù)案例:統(tǒng)計(jì)工作日到訪人數(shù)

醫(yī)院表 t_visit

CREATE TABLE t_visit (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    hospital_id INT,
    creatime DATETIME,
    visit_num INT
);

需求:

統(tǒng)計(jì)各醫(yī)院在工作日(周一到周五)的就診人數(shù)

錯(cuò)誤寫法:索引完全失效!

SELECT SUM(visit_num)
FROM t_visit
WHERE WEEKDAY(creatime) < 5;

解釋:

  • Creatime 上套函數(shù) → 索引失效
  • 查詢 100W 行 → 全表掃描
  • 業(yè)務(wù)卡死

五、使用 STORED,企業(yè)級(jí)寫法來(lái)了

1)添加生成列

ALTER TABLE t_visit
  ADD COLUMN is_workday TINYINT
    GENERATED ALWAYS AS (
      CASE WHEN WEEKDAY(creatime) < 5 THEN 1 ELSE 0 END
    ) STORED,
  ADD INDEX idx_visit_workday (is_workday, creatime);

2)正確查詢寫法

SELECT
    hospital_id,
    SUM(visit_num)
FROM t_visit
WHERE
    is_workday = 1
    AND creatime BETWEEN '2025-01-01' AND '2025-02-01'
GROUP BY hospital_id;

EXPLAIN 顯示:

  • type = range
  • key = idx_visit_workday
  • 幾萬(wàn)行 → 幾千行
  • 性能提升 5~30 倍

六、為什么企業(yè)更喜歡 STORED 而不是 VIRTUAL?

維度VIRTUALSTORED
存儲(chǔ)方式不落盤落盤
查詢成本每查都計(jì)算不需要計(jì)算
能否建 index老版本不支持、多版本有限制全版本支持,生產(chǎn)常用
性能適合小數(shù)據(jù)適合大數(shù)據(jù)、OLTP、高并發(fā)

大量業(yè)務(wù)都在用:

  • 是否工作日
  • 是否節(jié)假日
  • 是否逾期
  • 是否有效
  • 金額區(qū)間分類(如大單、中單、小單)
  • 年齡段分類
  • 設(shè)備狀態(tài)派生字段

只要是某列可以推導(dǎo)出來(lái)的值,且要做過濾、排序、聚合,80% 的情況下會(huì)用 STORED。

七、STORED 生成列 + dim_date = 雙劍合璧最強(qiáng)方案

在 BI / 數(shù)倉(cāng)中常用維表:

CREATE TABLE dim_date (
    date_key DATE PRIMARY KEY,
    weekday TINYINT,
    is_workday TINYINT,
    is_holiday TINYINT,
    holiday_name VARCHAR(20)
);

事實(shí)表:

ALTER TABLE t_visit
ADD visit_date DATE GENERATED ALWAYS AS (DATE(creatime)) STORED,
ADD INDEX (visit_date);

查詢:

SELECT
    v.hospital_id,
    SUM(v.visit_num)
FROM t_visit v
JOIN dim_date d ON v.visit_date = d.date_key
WHERE 
    d.is_workday = 1
GROUP BY v.hospital_id;

優(yōu)勢(shì):

  • 超高性能
  • 法定節(jié)假日、調(diào)休隨便改
  • 報(bào)表、看板、數(shù)據(jù)集市都復(fù)用 dim_date
  • 企業(yè)統(tǒng)一口徑

八、生產(chǎn)注意事項(xiàng)

  1. 生成列不能手工 INSERT / UPDATE
  2. 表插入非常頻繁時(shí),STORED 會(huì)多一次計(jì)算成本(但一般可以接受)
  3. 表過大時(shí),修改表結(jié)構(gòu)添加 STORED 列要注意線上壓力
  4. 建立索引時(shí)一定要注意前導(dǎo)列(選擇性越高越好)
  5. 如果你的計(jì)算很復(fù)雜,可以考慮 STORED + 函數(shù)表達(dá)式預(yù)處理

九、總結(jié):一句話記住 STORED

STORED 生成列,是 MySQL 自動(dòng)計(jì)算、自動(dòng)維護(hù)、可建索引的派生字段。
它讓復(fù)雜 SQL 拆分成“插入時(shí)算一次,查詢時(shí)用高速索引”,
是 OLTP 性能優(yōu)化最常用、最實(shí)用也最容易被忽略的武器。

到此這篇關(guān)于MySQL STORED 生成列(Generated Column) 的使用小結(jié)的文章就介紹到這了,更多相關(guān)MySQL STORED 生成列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MySQL GROUP BY分組取字段最大值的方法示例

    MySQL GROUP BY分組取字段最大值的方法示例

    本文介紹了如何使用MySQL的GROUPBY語(yǔ)句結(jié)合MAX函數(shù)來(lái)實(shí)現(xiàn)分組取字段最大值的操作,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • mysql的約束及實(shí)例分析

    mysql的約束及實(shí)例分析

    這篇文章主要介紹了mysql的約束及實(shí)例分析,真正約束字段的是數(shù)據(jù)類型,但是數(shù)據(jù)類型約束很單一,需要有一些額外的約束,更好的保證數(shù)據(jù)的合法性,從業(yè)務(wù)邏輯角度保證數(shù)據(jù)的正確性,需要的朋友可以參考下
    2023-07-07
  • Mysql中g(shù)roup by 使用中發(fā)現(xiàn)的問題

    Mysql中g(shù)roup by 使用中發(fā)現(xiàn)的問題

    當(dāng)使用MySQL的GROUP BY語(yǔ)句時(shí),根據(jù)指定的列對(duì)結(jié)果進(jìn)行分組,這種情況通常是由于在 GROUP BY 中選擇的字段與其他非聚合字段不兼容,或者在 SELECT 子句中沒有正確使用聚合函數(shù)所導(dǎo)致的,本文給大家介紹Mysql中g(shù)roup by 使用中發(fā)現(xiàn)的問題,感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • MySQL錯(cuò)誤ERROR 2002 (HY000): Can''t connect to local MySQL server through socket

    MySQL錯(cuò)誤ERROR 2002 (HY000): Can''t connect to local MySQL ser

    這篇文章主要介紹了MySQL錯(cuò)誤ERROR 2002 (HY000): Can't connect to local MySQL server through socket,需要的朋友可以參考下
    2014-10-10
  • Linux下編譯安裝Mysql 5.5的簡(jiǎn)單步驟

    Linux下編譯安裝Mysql 5.5的簡(jiǎn)單步驟

    Linux下面因?yàn)閺腗ySQL 5.5開始使用cmake來(lái)做config了,所以編譯安裝的會(huì)和5.1版本有些區(qū)別。不過總體來(lái)說還是差別不大
    2015-08-08
  • 在IntelliJ IDEA中使用Java連接MySQL數(shù)據(jù)庫(kù)的方法詳解

    在IntelliJ IDEA中使用Java連接MySQL數(shù)據(jù)庫(kù)的方法詳解

    這篇文章主要介紹了在IntelliJ IDEA中使用Java連接MySQL數(shù)據(jù)庫(kù)的方法詳解,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • MySQL三種常用存儲(chǔ)引擎InnoDB、MyISAM、Memory深度解析

    MySQL三種常用存儲(chǔ)引擎InnoDB、MyISAM、Memory深度解析

    在線教程千萬(wàn)篇,為什么你的 SQL 還是慢?因?yàn)闆]理解存儲(chǔ)引擎的底層機(jī)制,本文將帶你從源碼角度徹底搞懂 InnoDB 行鎖、聚簇索引,并給出生產(chǎn)環(huán)境的最優(yōu)選型,需要的朋友可以參考下
    2026-05-05
  • 將SQL查詢結(jié)果保存為新表的方法實(shí)例

    將SQL查詢結(jié)果保存為新表的方法實(shí)例

    有時(shí)我們要把查詢的結(jié)果保存到新表里,創(chuàng)建新表,查詢,插入顯得十分麻煩,下面這篇文章主要給大家介紹了關(guān)于將SQL查詢結(jié)果保存為新表的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 親手教你怎樣創(chuàng)建一個(gè)簡(jiǎn)單的mysql數(shù)據(jù)庫(kù)

    親手教你怎樣創(chuàng)建一個(gè)簡(jiǎn)單的mysql數(shù)據(jù)庫(kù)

    數(shù)據(jù)庫(kù)是存放數(shù)據(jù)的“倉(cāng)庫(kù)”,維基百科對(duì)此形象地描述為“電子化文件柜”,這篇文章主要介紹了親手教你怎樣創(chuàng)建一個(gè)簡(jiǎn)單的mysql數(shù)據(jù)庫(kù),需要的朋友可以參考下
    2022-11-11
  • win10 安裝mysql 8.0.18-winx64的步驟詳解

    win10 安裝mysql 8.0.18-winx64的步驟詳解

    這篇文章主要介紹了win10 安裝mysql 8.0.18-winx64的步驟,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評(píng)論

都匀市| 上犹县| 呼图壁县| 新津县| 淅川县| 独山县| 巴东县| 手游| 资源县| 玉田县| 万安县| 德江县| 新疆| 额尔古纳市| 日照市| 昭觉县| 汽车| 苏州市| 崇义县| 桂东县| 双峰县| 昌邑市| 吉安市| 清水河县| 北票市| 唐山市| 新晃| 改则县| 高雄市| 开远市| 长汀县| 巴里| 茌平县| 资溪县| 乌兰察布市| 衢州市| 冀州市| 宜宾市| 林口县| 清苑县| 清丰县|