<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      MySQL---like的模糊查詢如何優化+虛擬列

      ?MySQL中like的模糊查詢如何優化

      當然還可以ES等 這里只說mysql怎么搞

      典型回答

      在MySQL中,使用like進行模糊查詢,在一定情況下是無法使用索引的。如下所示:

      • ●當like值前后都有匹配符時%abc%,無法使用索引

      • ●當like值前有匹配符時%abc,無法使用索引

      • ●當like值后有匹配符時'abc%',可以使用索引

      那么,like %abc真的無法優化了嗎?

      我們之所以會使用%abc來查詢說明表中的name可能包含以abc結尾的字符串,如果以abc%說明有以abc開頭的字符串。

      假設我們要向表中的name寫入123abc,我們可以將這一列反轉過來,即cba321插入到一個冗余列v_name中,并為這一列建立索引:

      接下來在查詢的時候,我們就可以使用v_name列進行模糊查詢了

      當然這樣看起來有點麻煩,表中如果已經有了很多數據,還需要利用update語句反轉name到v_name中,如果數據量大了(幾百萬或上千萬條記錄)更新一下v_name耗時也比較長,同時也會增大表空間。

      MySQL5.7.6之后,新增了虛擬列功能

      幸運的是在MySQL5.7.6之后,新增了虛擬列功能(如果不是>=5.7.6,只能用上面的土方法)為一個列建立一個虛擬列,并為虛擬列建立索引,在查詢時where中like條件改為虛擬列,就可以使用索引了。

      我們再進行查詢,就會走索引了

      當然如果你要查詢like 'abc%'和like '%abc',你只需要使用一個union

      可以看到,除了union result合并倆個語句,另外倆個查詢都已經走索引了。如果你只想需要查詢name,甚至可以使用覆蓋索引進一步提升性能

      虛擬列可以指定為VIRTUAL或STORED,VIRTUAL不會將虛擬列存儲到磁盤中,在使用時MySQL會現計算虛擬列的值,STORED會存儲到磁盤中,相當于我們手動創建的冗余列。所以:如果你的磁盤足夠大,可以使用STORED方式,這樣在查詢時速度會更快一些。

      如果你的數據量級較大,不使用反向查詢的方式耗時會非常高。你可以使用如下sql測試虛擬列的效果:

       
      java
      體驗AI代碼助手
      代碼解讀
      復制代碼
      
      /* 建表 */
      
      CREATE TABLE test (
        id INT AUTO_INCREMENT PRIMARY KEY,
        name VARCHAR(50),
        INDEX idx_name (name)
      ) CHARACTER SET utf8;
      
      
      /* 創建一個存儲過程,向test表中寫入2000000條數據,200條數據中abc字符前包含一些隨機字符(用于測試like '%abc'的情況),200條數據中abc字符后包含一些隨機字符(用于測試like 'abc%'的情況),其余行不包含abc字符 */
      
      DELIMITER //
      
      CREATE PROCEDURE InsertTestData()
      BEGIN
        DECLARE i INT DEFAULT 1;
        
        WHILE i <= 2000000 DO
          IF i <= 200 THEN
            SET @randomPrefix1 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), CHAR(FLOOR(RAND() * 26) + 97), CHAR(FLOOR(RAND() * 26) + 48));
            SET @randomString1 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), CHAR(FLOOR(RAND() * 26) + 97), CHAR(FLOOR(RAND() * 26) + 48));
            SET @randomName1 = CONCAT(@randomPrefix1, @randomString1, 'abc');
            INSERT INTO test (name) VALUES (@randomName1);
          ELSEIF i <= 400 THEN
            SET @randomString2 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), CHAR(FLOOR(RAND() * 26) + 97), CHAR(FLOOR(RAND() * 26) + 48));
            SET @randomName2 = CONCAT('abc', @randomString2);
            INSERT INTO test (name) VALUES (@randomName2);
          ELSE
            SET @randomName3 = CONCAT(CHAR(FLOOR(RAND() * 26) + 65), CHAR(FLOOR(RAND() * 26) + 97), CHAR(FLOOR(RAND() * 26) + 48));
            INSERT INTO test (name) VALUES (@randomName3);
          END IF;
          
          SET i = i + 1;
        END WHILE;
      END //
      
      DELIMITER ;
      
      
      
      
      /* 調用存儲過程,這里執行的會很慢 */
      
      call InsertTestData();
      
      
      
      /* 建立虛擬列 */
      alter table test add column `v_name` varchar(50) generated always as (reverse(name));
      /* 為虛擬列創建索引 */
      alter table test add index `idx_name_virt`(v_name);
      
      
      /* 使用虛擬列模糊查詢 */
      select * from test where v_name like 'cba%'
      union
      select * from test where name like 'abc%'
      
      
      
      /* 不使用虛擬列模糊查詢 */
      select * from test where name like 'abc%'
      union
      select * from test where name like '%abc'

      image.png

      image.png

      MySQL5.7.6 虛擬列功能

      MySQL 5.7 引入了虛擬列(Generated Columns),這些列的值是通過表達式計算得出的,而不是直接存儲在表中的。虛擬列可以分為兩種類型:VIRTUAL 和 STORED。以下是虛擬列的好處和壞處:

      好處

      1. 簡化查詢

        • 虛擬列可以簡化復雜的查詢,尤其是當查詢中需要頻繁使用某個表達式時。通過將表達式定義為虛擬列,可以直接查詢該列,而不需要在每次查詢時重復計算。
      2. 數據一致性

        • 虛擬列的值是根據其他列的值自動計算的,因此可以確保數據的一致性。如果基礎列的值發生變化,虛擬列的值會自動更新,避免了手動維護數據一致性的麻煩。
      3. 減少冗余

        • 使用虛擬列可以避免存儲冗余數據。例如,如果你需要根據某些列的值計算出一個結果,并且這個結果不需要頻繁更新,可以使用虛擬列來動態計算,而不需要將結果存儲在表中。
      4. 索引支持

        • 虛擬列可以被索引,這可以顯著提高查詢性能。特別是當虛擬列的計算結果經常用于查詢條件時,創建索引可以加速查詢。
      5. 靈活性

        • 虛擬列可以根據需要定義復雜的表達式,提供更高的靈活性。你可以根據業務需求動態生成數據,而不需要修改表結構或應用程序代碼。

      壞處

      1. 性能開銷

        • VIRTUAL 虛擬列的值在每次查詢時動態計算,這可能會增加查詢的計算開銷,尤其是在表達式復雜或數據量大的情況下。雖然 STORED 虛擬列的值是預先計算并存儲的,但在插入或更新數據時會有額外的計算和存儲開銷。
      2. 存儲空間

        • STORED 虛擬列的值是實際存儲在表中的,因此會增加表的存儲空間。如果虛擬列的計算結果較大或表中有大量數據,這可能會導致存儲需求顯著增加。
      3. 復雜性增加

        • 虛擬列的定義可能會增加表結構的復雜性,尤其是在定義復雜的表達式時。這可能會使表的設計和維護變得更加困難。
      4. 兼容性問題

        • 虛擬列是 MySQL 5.7 引入的特性,因此在較舊的 MySQL 版本中無法使用。如果你的應用程序需要兼容舊版本的 MySQL,使用虛擬列可能會導致兼容性問題。
      5. 索引限制

        • 雖然虛擬列可以被索引,但并不是所有的表達式都支持索引。某些復雜的表達式可能無法創建索引,這可能會限制虛擬列在查詢優化中的應用。

      總結

      虛擬列在 MySQL 5.7 中提供了強大的功能,可以簡化查詢、提高數據一致性并減少冗余。然而,它們也可能帶來性能開銷、存儲空間增加和復雜性提升等問題。在使用虛擬列時,需要根據具體的業務需求和性能要求進行權衡,確保其帶來的好處大于潛在的缺點。

      posted @ 2025-07-03 09:30  CharyGao  閱讀(51)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产精品嫩草99av在线| 精品无码老熟妇magnet| 成人精品老熟妇一区二区| 元码人妻精品一区二区三区9| 亚洲第一极品精品无码久久| 国精偷拍一区二区三区| 国产毛片精品av一区二区| 亚洲av片在线免费观看| 国产欲女高潮正在播放| 成av人电影在线观看| 久久国产精品不只是精品| 亚洲人成小说网站色在线| 无码中文av波多野结衣一区| 最新国产精品亚洲| 国产精品区视频中文字幕 | 亚洲免费视频一区二区三区| 亚洲高清日韩heyzo| 黄色免费在线网址| 99精品热在线在线观看视| 亚洲国产精品特色大片观看完整版| 久久人体视频| 四虎永久免费精品视频| 熟妇的奶头又大又长奶水视频| 亚洲码国产精品高潮在线| 精品一区二区免费不卡| 最新国产精品精品视频| 欧美亚洲熟妇一区二区三区| 小嫩批日出水无码视频免费| 色婷婷日日躁夜夜躁| 久久96热在精品国产高清| 国产成年码av片在线观看| 99九九热久久只有精品| 曰韩无码二三区中文字幕| 97一期涩涩97片久久久久久久| 日韩精品中文字幕人妻| 国产亚洲一区二区三区四区| 亚洲精品成人片在线观看精品字幕| 青海省| 欧美成人精品三级网站视频| 日本高清视频色欧WWW| 中文字幕在线国产精品|