本文目錄一覽:
- 1、滿足不定多個條件,該如何查詢MySQL數據庫?
- 2、超詳細MySQL數據庫優化
- 3、MySQL數據庫密碼複雜度配置
- 4、求高手優化MySQL數據庫,數據庫反應太慢。
- 5、MYSQL數據庫中的複雜查詢 4個班級.我要查詢每個班男生人數大於女生人數的班級,代碼如何寫
- 6、mysql數據庫查詢
滿足不定多個條件,該如何查詢MySQL數據庫?
該類問題可以採用以下兩種方法實現:
使用動態生成sql語句進行實現,根據不同查詢條件控制生成不同的查詢SQL語句,也就是where 後面的內容;
利用開發系統控制where條件,此方法最佳,不但可以控制單多查詢條件,也可以實現複雜多條件的查詢,例如 = ,,,like等複雜查詢,亦可對排序需求進行控制;
以上為大概解決方法,如有疑問 請追問~~ 謝謝
+
deng d
de
`-
declare @str varchar(1000)=”;
declare @i int =0;
set @str=’select * from master.dbo.spt_values where 1=1′
if @i=0
set @str=@str+’ and [type]=”p”’
Exec (@str)
超詳細MySQL數據庫優化
數據庫優化一方面是找出系統的瓶頸,提高MySQL數據庫的整體性能,而另一方面需要合理的結構設計和參數調整,以提高用戶的相應速度,同時還要儘可能的節約系統資源,以便讓系統提供更大的負荷.
1. 優化一覽圖
2. 優化
筆者將優化分為了兩大類,軟優化和硬優化,軟優化一般是操作數據庫即可,而硬優化則是操作服務器硬件及參數設置.
2.1 軟優化
2.1.1 查詢語句優化
1.首先我們可以用EXPLAIN或DESCRIBE(簡寫:DESC)命令分析一條查詢語句的執行信息.
2.例:
顯示:
其中會顯示索引和查詢數據讀取數據條數等信息.
2.1.2 優化子查詢
在MySQL中,盡量使用JOIN來代替子查詢.因為子查詢需要嵌套查詢,嵌套查詢時會建立一張臨時表,臨時表的建立和刪除都會有較大的系統開銷,而連接查詢不會創建臨時表,因此效率比嵌套子查詢高.
2.1.3 使用索引
索引是提高數據庫查詢速度最重要的方法之一,關於索引可以參高筆者MySQL數據庫索引一文,介紹比較詳細,此處記錄使用索引的三大注意事項:
2.1.4 分解表
對於字段較多的表,如果某些字段使用頻率較低,此時應當,將其分離出來從而形成新的表,
2.1.5 中間表
對於將大量連接查詢的表可以創建中間表,從而減少在查詢時造成的連接耗時.
2.1.6 增加冗餘字段
類似於創建中間表,增加冗餘也是為了減少連接查詢.
2.1.7 分析表,,檢查表,優化表
分析表主要是分析表中關鍵字的分佈,檢查表主要是檢查表中是否存在錯誤,優化表主要是消除刪除或更新造成的表空間浪費.
1. 分析表: 使用 ANALYZE 關鍵字,如ANALYZE TABLE user;
2. 檢查表: 使用 CHECK關鍵字,如CHECK TABLE user [option]
option 只對MyISAM有效,共五個參數值:
3. 優化表:使用OPTIMIZE關鍵字,如OPTIMIZE [LOCAL|NO_WRITE_TO_BINLOG] TABLE user;
LOCAL|NO_WRITE_TO_BINLOG都是表示不寫入日誌.,優化表只對VARCHAR,BLOB和TEXT有效,通過OPTIMIZE TABLE語句可以消除文件碎片,在執行過程中會加上只讀鎖.
2.2 硬優化
2.2.1 硬件三件套
1.配置多核心和頻率高的cpu,多核心可以執行多個線程.
2.配置大內存,提高內存,即可提高緩存區容量,因此能減少磁盤I/O時間,從而提高響應速度.
3.配置高速磁盤或合理分佈磁盤:高速磁盤提高I/O,分佈磁盤能提高並行操作的能力.
2.2.2 優化數據庫參數
優化數據庫參數可以提高資源利用率,從而提高MySQL服務器性能.MySQL服務的配置參數都在my.cnf或my.ini,下面列出性能影響較大的幾個參數.
2.2.3 分庫分表
因為數據庫壓力過大,首先一個問題就是高峰期系統性能可能會降低,因為數據庫負載過高對性能會有影響。另外一個,壓力過大把你的數據庫給搞掛了怎麼辦?所以此時你必須得對系統做分庫分表 + 讀寫分離,也就是把一個庫拆分為多個庫,部署在多個數據庫服務上,這時作為主庫承載寫入請求。然後每個主庫都掛載至少一個從庫,由從庫來承載讀請求。
2.2.4 緩存集群
如果用戶量越來越大,此時你可以不停的加機器,比如說系統層面不停加機器,就可以承載更高的並發請求。然後數據庫層面如果寫入並發越來越高,就擴容加數據庫服務器,通過分庫分表是可以支持擴容機器的,如果數據庫層面的讀並發越來越高,就擴容加更多的從庫。但是這裡有一個很大的問題:數據庫其實本身不是用來承載高並發請求的,所以通常來說,數據庫單機每秒承載的並發就在幾千的數量級,而且數據庫使用的機器都是比較高配置,比較昂貴的機器,成本很高。如果你就是簡單的不停的加機器,其實是不對的。所以在高並發架構里通常都有緩存這個環節,緩存系統的設計就是為了承載高並發而生。所以單機承載的並發量都在每秒幾萬,甚至每秒數十萬,對高並發的承載能力比數據庫系統要高出一到兩個數量級。所以你完全可以根據系統的業務特性,對那種寫少讀多的請求,引入緩存集群。具體來說,就是在寫數據庫的時候同時寫一份數據到緩存集群里,然後用緩存集群來承載大部分的讀請求。這樣的話,通過緩存集群,就可以用更少的機器資源承載更高的並發。
一個完整而複雜的高並發系統架構中,一定會包含:各種複雜的自研基礎架構系統。各種精妙的架構設計.因此一篇小文頂多具有拋磚引玉的效果,但是數據庫優化的思想差不多就這些了.
MySQL數據庫密碼複雜度配置
1、登錄
2、修改密碼
3、配置密碼複雜度
需要有validate_password.dll文件支持,查詢是否有插件
安裝插件
4、查看密碼複雜度
validate_password_policy :密碼安全策略
validate_password_length :密碼最少長度
validate_password_number_count :最少數字字符數
validate_password_mixed_case_count :最少大寫和小寫字符數(同時有大寫和小寫)
validate_password_special_char_count :最少特殊字符數
求高手優化MySQL數據庫,數據庫反應太慢。
在開始演示之前,我們先介紹下兩個概念。
概念一,數據的可選擇性基數,也就是常說的cardinality值。
查詢優化器在生成各種執行計劃之前,得先從統計信息中取得相關數據,這樣才能估算每步操作所涉及到的記錄數,而這個相關數據就是cardinality。簡單來說,就是每個值在每個字段中的唯一值分佈狀態。
比如表t1有100行記錄,其中一列為f1。f1中唯一值的個數可以是100個,也可以是1個,當然也可以是1到100之間的任何一個數字。這裡唯一值越的多少,就是這個列的可選擇基數。
那看到這裡我們就明白了,為什麼要在基數高的字段上建立索引,而基數低的的字段建立索引反而沒有全表掃描來的快。當然這個只是一方面,至於更深入的探討就不在我這篇探討的範圍了。
概念二,關於HINT的使用。
這裡我來說下HINT是什麼,在什麼時候用。
HINT簡單來說就是在某些特定的場景下人工協助MySQL優化器的工作,使她生成最優的執行計劃。一般來說,優化器的執行計劃都是最優化的,不過在某些特定場景下,執行計劃可能不是最優化。
比如:表t1經過大量的頻繁更新操作,(UPDATE,DELETE,INSERT),cardinality已經很不準確了,這時候剛好執行了一條SQL,那麼有可能這條SQL的執行計劃就不是最優的。為什麼說有可能呢?
來看下具體演示
譬如,以下兩條SQL,
A:
select * from t1 where f1 = 20;
B:
select * from t1 where f1 = 30;
如果f1的值剛好頻繁更新的值為30,並且沒有達到MySQL自動更新cardinality值的臨界值或者說用戶設置了手動更新又或者用戶減少了sample page等等,那麼對這兩條語句來說,可能不準確的就是B了。
這裡順帶說下,MySQL提供了自動更新和手動更新表cardinality值的方法,因篇幅有限,需要的可以查閱手冊。
那回到正題上,MySQL 8.0 帶來了幾個HINT,我今天就舉個index_merge的例子。
示例表結構:
mysql desc t1;+————+————–+——+—–+———+—————-+| Field | Type | Null | Key | Default | Extra |+————+————–+——+—–+———+—————-+| id | int(11) | NO | PRI | NULL | auto_increment || rank1 | int(11) | YES | MUL | NULL | || rank2 | int(11) | YES | MUL | NULL | || log_time | datetime | YES | MUL | NULL | || prefix_uid | varchar(100) | YES | | NULL | || desc1 | text | YES | | NULL | || rank3 | int(11) | YES | MUL | NULL | |+————+————–+——+—–+———+—————-+7 rows in set (0.00 sec)
表記錄數:
mysql select count(*) from t1;+———-+| count(*) |+———-+| 32768 |+———-+1 row in set (0.01 sec)
這裡我們兩條經典的SQL:
SQL C:
select * from t1 where rank1 = 1 or rank2 = 2 or rank3 = 2;
SQL D:
select * from t1 where rank1 =100 and rank2 =100 and rank3 =100;
表t1實際上在rank1,rank2,rank3三列上分別有一個二級索引。
那我們來看SQL C的查詢計劃。
顯然,沒有用到任何索引,掃描的行數為32034,cost為3243.65。
mysql explain format=json select * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “3243.65” }, “table”: { “table_name”: “t1”, “access_type”: “ALL”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “rows_examined_per_scan”: 32034, “rows_produced_per_join”: 115, “filtered”: “0.36”, “cost_info”: { “read_cost”: “3232.07”, “eval_cost”: “11.58”, “prefix_cost”: “3243.65”, “data_read_per_join”: “49K” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們加上hint給相同的查詢,再次看看查詢計劃。
這個時候用到了index_merge,union了三個列。掃描的行數為1103,cost為441.09,明顯比之前的快了好幾倍。
mysql explain format=json select /*+ index_merge(t1) */ * from t1 where rank1 =1 or rank2 = 2 or rank3 = 2\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “441.09” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “union(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1103, “rows_produced_per_join”: 1103, “filtered”: “100.00”, “cost_info”: { “read_cost”: “330.79”, “eval_cost”: “110.30”, “prefix_cost”: “441.09”, “data_read_per_join”: “473K” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank1` = 1) or (`ytt`.`t1`.`rank2` = 2) or (`ytt`.`t1`.`rank3` = 2))” } }}1 row in set, 1 warning (0.00 sec)
我們再看下SQL D的計劃:
不加HINT,
mysql explain format=json select * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “534.34” }, “table”: { “table_name”: “t1”, “access_type”: “ref”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “idx_rank1”, “used_key_parts”: [ “rank1” ], “key_length”: “5”, “ref”: [ “const” ], “rows_examined_per_scan”: 555, “rows_produced_per_join”: 0, “filtered”: “0.07”, “cost_info”: { “read_cost”: “478.84”, “eval_cost”: “0.04”, “prefix_cost”: “534.34”, “data_read_per_join”: “176” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100))” } }}1 row in set, 1 warning (0.00 sec)
加了HINT,
mysql explain format=json select /*+ index_merge(t1)*/ * from t1 where rank1 =100 and rank2 =100 and rank3 =100\G*************************** 1. row ***************************EXPLAIN: { “query_block”: { “select_id”: 1, “cost_info”: { “query_cost”: “5.23” }, “table”: { “table_name”: “t1”, “access_type”: “index_merge”, “possible_keys”: [ “idx_rank1”, “idx_rank2”, “idx_rank3” ], “key”: “intersect(idx_rank1,idx_rank2,idx_rank3)”, “key_length”: “5,5,5”, “rows_examined_per_scan”: 1, “rows_produced_per_join”: 1, “filtered”: “100.00”, “cost_info”: { “read_cost”: “5.13”, “eval_cost”: “0.10”, “prefix_cost”: “5.23”, “data_read_per_join”: “440” }, “used_columns”: [ “id”, “rank1”, “rank2”, “log_time”, “prefix_uid”, “desc1”, “rank3” ], “attached_condition”: “((`ytt`.`t1`.`rank3` = 100) and (`ytt`.`t1`.`rank2` = 100) and (`ytt`.`t1`.`rank1` = 100))” } }}1 row in set, 1 warning (0.00 sec)
對比下以上兩個,加了HINT的比不加HINT的cost小了100倍。
總結下,就是說表的cardinality值影響這張的查詢計劃,如果這個值沒有正常更新的話,就需要手工加HINT了。相信MySQL未來的版本會帶來更多的HINT。
MYSQL數據庫中的複雜查詢 4個班級.我要查詢每個班男生人數大於女生人數的班級,代碼如何寫
select * from classes where (select count(*) from classes where sex = ‘男’)(select count(*) from classes where sex = ‘女’)
mysql數據庫查詢
建議您修改表的結構
建立一個子表keyword,子表記錄有3個字段id,keyword,和sid
其中id主鍵自增(除了區分沒有其他用處),sid對應您原來保存keyword字段的記錄的id,keyword對應一個關鍵詞(只有一個!!!)
舉個例子,一篇關於電子商務的文章,保存在表news裏面,文章的id為9。該文章有3個關鍵字「b2b」「生鮮」「藍籌」
如何保存該文章的關鍵字呢?
在keyword表中如下書寫:
id keyword sid
1 b2b 9
2 生鮮 9
3 藍籌 9
您看明白了么?這就把「一個數組中有多少元素」的問題轉化為了「一個表keyword中sid為9的記錄有多少條」的問題!!!因為數據庫中是沒有數組這一數據結構的!!!所以剛剛的思路有問題!
做了子表以後,不但可以用關聯查詢解決您的問題,還無形中對數據庫進行了優化,因為您說了,該字段的長度不定,所以存儲單元一定是按照最長的記錄來開闢的,大數據時很浪費數據庫資源。
使用了子表,keyword字段就真的只有一個關鍵詞的長度,大大降低了數據庫的冗餘。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/227364.html