日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL拆分实现与注意事项

發布時間:2025/3/20 数据库 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL拆分实现与注意事项 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SQL拆分的背景

任何系統的設計都是在不斷的迭代中改進的,在系統最初的階段,能夠最快的完成功能是首要任務,這就會導致我們在寫數據查詢時使用了大量的關聯查詢。而當系統用戶慢慢增加到我們不得不分庫分表的時候,原先的關聯查詢就會失效,這就迫使我們不得不將之前的關聯查詢拆分開,然后利用代碼邏輯進行關聯操作

如何拆分SQL(left join 拆分)

其實,各種關聯操作的拆分思想基本是一樣的,只是在不同的情況下,我們可能會忽略掉某些問題而出錯。所以我只說了除了第一個left操作。

原SQL:SELECT u.* ,o.time FROM user u LEFT JOIN order o ON o.userId = u.id
拆分步驟:

  • 先查出user表的結果集:SELECT u.* FROM user
  • 將user表中與order表關聯的字段的值都取出來(這里是user表的主鍵):userIds
  • 利用userIds進行 in()函數查回order表的關聯字段及其他字段的結果集:SELECT o.time,o.userId FROM order o WHERE o.id IN (userIds)
  • 在代碼中利用關聯字段的結果進行數據的left 操作:即給第1步的結果集中加上order表的time字段的值
  • 簡化拆分工作的辦法是,寫一個工具類,根據自身的項目情況,針對性的寫出left 、inner、in、groupby、分頁、orderby等函數的公共方法

    拆分注意事項

    1.關聯子表有篩選條件的left join,在代碼里的 left join操作需要變成inner join操作

    原SQL:
    SELECT u.* ,o.time FROM user u LEFT JOIN order o ON o.userId = u.id WHERE o.time>‘2019-3-14 AND u.id BETWEEN 100 AND 1000’
    拆分偽代碼:
    List list1 = "SELECT u.* FROM user WHERE id BETWEEN 100 AND 1000’;
    List list2 = "SELECT o.userId FROM order WHERE o.time>'2019-3-14 AND o.userId IN ( list1里的所有ID) ";
    List result = list2與list1作inner join操作(而不是left 操作)
    這是因為子表有條件之后,將不再以主表的數據為準了

    2. 關聯子表會將主表的數據篩選掉的情況(不論是inner、left), 分頁操作需要將兩個表的數據拿到后在代碼里分頁

  • 子表有where條件的
  • 子表中不存在關聯字段對應的值
  • 注:強烈不推薦在代碼里分頁,在代碼里分頁的最大問題是處理數據量會很大,會影響系統性能。
    如果有分頁,盡量想辦法在SQL里完成;實在不行,可根據具體情況分析避免。

    3. 如果主表與子表是 一對多的關系(不論是inner、left),子表的數據條數決定了主表的數據條數。

    這個體現在代碼里就是,在利用map建立主表與子表的對應關系時,我們可以用ArrayListMultimap:
    偽代碼:

    ArrayListMultimap<String, Object[]> map = ArrayListMultimap.create();for (Object[] arr : list) { // list數據是子表的數據,arr[0]是關聯字段map.put(arr[0].toString(), arr);}

    4. 在作in操作時特別需要注意, 如果in的參數個數為0,則不再需要查SQL

    5. 要判斷in條件參數個數,如果太大會報導致報錯(這會是一個隱藏bug,直到數據量大了才會發現)。目前的解決辦法分成多次in查詢(太慢可考慮線程)

    多線程in查詢可參考:https://gitee.com/lovewx/codes/be51427wngzfrcmqsivua79

    6. 拆分SQL時,要考慮索引失效的問題,即關聯查詢時可以用到索引,而拆開之后就不能用到索引了

    總結

    以上是生活随笔為你收集整理的SQL拆分实现与注意事项的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。