8 種最坑的SQL錯誤用法

  • 1、LIMIT 語句

  • 2、隱式轉換

  • 3、關聯更新、刪除

  • 4、混合排序

  • 5、EXISTS語句

  • 6、條件下推

  • 7、提前縮小范圍

  • 8、中間結果集下推

  • 總結


sql語句的執行順序:

FROM
<left_table>ON
<join_condition><join_type>JOIN
<right_table>WHERE
<where_condition>GROUP?BY
<group_by_list>HAVING
<having_condition>SELECTDISTINCT
<select_list>ORDER?BY
<order_by_condition>LIMIT
<limit_number>

1、LIMIT 語句

分頁查詢是最常用的場景之一,但也通常也是最容易出問題的地方。比如對于下面簡單的語句,一般 DBA 想到的辦法是在 type, name, create_time 字段上加組合索引。這樣條件排序都能有效的利用到索引,性能迅速提升。

SELECT?*
FROM???operation
WHERE??type?=?'SQLStats'AND?name?=?'SlowLog'
ORDER??BY?create_time
LIMIT??1000,?10;

好吧,可能90%以上的 DBA 解決該問題就到此為止。但當 LIMIT 子句變成 “LIMIT 1000000,10” 時,程序員仍然會抱怨:我只取10條記錄為什么還是慢?

要知道數據庫也并不知道第1000000條記錄從什么地方開始,即使有索引也需要從頭計算一次。出現這種性能問題,多數情形下是程序員偷懶了。

在前端數據瀏覽翻頁,或者大數據分批導出等場景下,是可以將上一頁的最大值當成參數作為查詢條件的。SQL 重新設計如下:

SELECT???*
FROM?????operation
WHERE????type?=?'SQLStats'
AND??????name?=?'SlowLog'
AND??????create_time?>?'2017-03-16?14:00:00'
ORDER?BY?create_time?limit?10;

在新設計下查詢時間基本固定,不會隨著數據量的增長而發生變化。

2、隱式轉換

SQL語句中查詢變量和字段定義類型不匹配是另一個常見的錯誤。比如下面的語句:

mysql>?explain?extended?SELECT?*>?FROM???my_balance?b>?WHERE??b.bpn?=?14000000123>???????AND?b.isverified?IS?NULL?;
mysql>?show?warnings;
|?Warning?|?1739?|?Cannot?use?ref?access?on?index?'bpn'?due?to?type?or?collation?conversion?on?field?'bpn'

其中字段 bpn 的定義為 varchar(20),MySQL 的策略是將字符串轉換為數字之后再比較。函數作用于表字段,索引失效。

上述情況可能是應用程序框架自動填入的參數,而不是程序員的原意。現在應用框架很多很繁雜,使用方便的同時也小心它可能給自己挖坑。

3、關聯更新、刪除

雖然 MySQL5.6 引入了物化特性,但需要特別注意它目前僅僅針對查詢語句的優化。對于更新或刪除需要手工重寫成 JOIN。

比如下面 UPDATE 語句,MySQL 實際執行的是循環/嵌套子查詢(DEPENDENT SUBQUERY),其執行時間可想而知。

UPDATE?operation?o
SET????status?=?'applying'
WHERE??o.id?IN?(SELECT?idFROM???(SELECT?o.id,o.statusFROM???operation?oWHERE??o.group?=?123AND?o.status?NOT?IN?(?'done'?)ORDER??BY?o.parent,o.idLIMIT??1)?t);

執行計劃:

+----+--------------------+-------+-------+---------------+---------+---------+-------+------+-----------------------------------------------------+
|?id?|?select_type????????|?table?|?type??|?possible_keys?|?key?????|?key_len?|?ref???|?rows?|?Extra???????????????????????????????????????????????|
+----+--------------------+-------+-------+---------------+---------+---------+-------+------+-----------------------------------------------------+
|?1??|?PRIMARY????????????|?o?????|?index?|???????????????|?PRIMARY?|?8???????|???????|?24???|?Using?where;?Using?temporary????????????????????????|
|?2??|?DEPENDENT?SUBQUERY?|???????|???????|???????????????|?????????|?????????|???????|??????|?Impossible?WHERE?noticed?after?reading?const?tables?|
|?3??|?DERIVED????????????|?o?????|?ref???|?idx_2,idx_5???|?idx_5???|?8???????|?const?|?1????|?Using?where;?Using?filesort?????????????????????????|
+----+--------------------+-------+-------+---------------+---------+---------+-------+------+-----------------------------------------------------+

重寫為 JOIN 之后,子查詢的選擇模式從 DEPENDENT SUBQUERY 變成 DERIVED,執行速度大大加快,從7秒降低到2毫秒。

UPDATE?operation?oJOIN??(SELECT?o.id,o.statusFROM???operation?oWHERE??o.group?=?123AND?o.status?NOT?IN?(?'done'?)ORDER??BY?o.parent,o.idLIMIT??1)?tON?o.id?=?t.id
SET????status?=?'applying'

執行計劃簡化為:

+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------------------------------------+
|?id?|?select_type?|?table?|?type?|?possible_keys?|?key???|?key_len?|?ref???|?rows?|?Extra???????????????????????????????????????????????|
+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------------------------------------+
|?1??|?PRIMARY?????|???????|??????|???????????????|???????|?????????|???????|??????|?Impossible?WHERE?noticed?after?reading?const?tables?|
|?2??|?DERIVED?????|?o?????|?ref??|?idx_2,idx_5???|?idx_5?|?8???????|?const?|?1????|?Using?where;?Using?filesort?????????????????????????|
+----+-------------+-------+------+---------------+-------+---------+-------+------+-----------------------------------------------------+

4、混合排序

MySQL 不能利用索引進行混合排序。但在某些場景,還是有機會使用特殊方法提升性能的。

SELECT?*
FROM???my_order?oINNER?JOIN?my_appraise?a?ON?a.orderid?=?o.id
ORDER??BY?a.is_reply?ASC,a.appraise_time?DESC
LIMIT??0,?20

執行計劃顯示為全表掃描:

+----+-------------+-------+--------+-------------+---------+---------+---------------+---------+-+
|?id?|?select_type?|?table?|?type???|?possible_keys?????|?key?????|?key_len?|?ref??????|?rows????|?Extra
+----+-------------+-------+--------+-------------+---------+---------+---------------+---------+-+
|??1?|?SIMPLE??????|?a?????|?ALL????|?idx_orderid?|?NULL????|?NULL????|?NULL????|?1967647?|?Using?filesort?|
|??1?|?SIMPLE??????|?o?????|?eq_ref?|?PRIMARY?????|?PRIMARY?|?122?????|?a.orderid?|???????1?|?NULL???????????|
+----+-------------+-------+--------+---------+---------+---------+-----------------+---------+-+

由于 is_reply 只有0和1兩種狀態,我們按照下面的方法重寫后,執行時間從1.58秒降低到2毫秒。

SELECT?*
FROM???((SELECT?*FROM???my_order?oINNER?JOIN?my_appraise?aON?a.orderid?=?o.idAND?is_reply?=?0ORDER??BY?appraise_time?DESCLIMIT??0,?20)UNION?ALL(SELECT?*FROM???my_order?oINNER?JOIN?my_appraise?aON?a.orderid?=?o.idAND?is_reply?=?1ORDER??BY?appraise_time?DESCLIMIT??0,?20))?t
ORDER??BY??is_reply?ASC,appraisetime?DESC
LIMIT??20;

5、EXISTS語句

MySQL 對待 EXISTS 子句時,仍然采用嵌套子查詢的執行方式。如下面的 SQL 語句:

SELECT?*
FROM???my_neighbor?nLEFT?JOIN?my_neighbor_apply?sraON?n.id?=?sra.neighbor_idAND?sra.user_id?=?'xxx'
WHERE??n.topic_status?<?4AND?EXISTS(SELECT?1FROM???message_info?mWHERE??n.id?=?m.neighbor_idAND?m.inuser?=?'xxx')AND?n.topic_type?<>?5

執行計劃為:

+----+--------------------+-------+------+-----+------------------------------------------+---------+-------+---------+?-----+
|?id?|?select_type????????|?table?|?type?|?possible_keys?????|?key???|?key_len?|?ref???|?rows????|?Extra???|
+----+--------------------+-------+------+?-----+------------------------------------------+---------+-------+---------+?-----+
|??1?|?PRIMARY????????????|?n?????|?ALL??|??|?NULL?????|?NULL????|?NULL??|?1086041?|?Using?where???????????????????|
|??1?|?PRIMARY????????????|?sra???|?ref??|??|?idx_user_id?|?123?????|?const?|???????1?|?Using?where??????????|
|??2?|?DEPENDENT?SUBQUERY?|?m?????|?ref??|??|?idx_message_info???|?122?????|?const?|???????1?|?Using?index?condition;?Using?where?|
+----+--------------------+-------+------+?-----+------------------------------------------+---------+-------+---------+?-----+

去掉 exists 更改為 join,能夠避免嵌套子查詢,將執行時間從1.93秒降低為1毫秒。

SELECT?*
FROM???my_neighbor?nINNER?JOIN?message_info?mON?n.id?=?m.neighbor_idAND?m.inuser?=?'xxx'LEFT?JOIN?my_neighbor_apply?sraON?n.id?=?sra.neighbor_idAND?sra.user_id?=?'xxx'
WHERE??n.topic_status?<?4AND?n.topic_type?<>?5

新的執行計劃:

+----+-------------+-------+--------+?-----+------------------------------------------+---------+?-----+------+?-----+
|?id?|?select_type?|?table?|?type???|?possible_keys?????|?key???????|?key_len?|?ref???|?rows?|?Extra?????????????????|
+----+-------------+-------+--------+?-----+------------------------------------------+---------+?-----+------+?-----+
|??1?|?SIMPLE??????|?m?????|?ref????|?|?idx_message_info???|?122?????|?const????|????1?|?Using?index?condition?|
|??1?|?SIMPLE??????|?n?????|?eq_ref?|?|?PRIMARY???|?122?????|?ighbor_id?|????1?|?Using?where??????|
|??1?|?SIMPLE??????|?sra???|?ref????|?|?idx_user_id?|?123?????|?const?????|????1?|?Using?where???????????|
+----+-------------+-------+--------+?-----+------------------------------------------+---------+?-----+------+?-----+

6、條件下推

外部查詢條件不能夠下推到復雜的視圖或子查詢的情況有:

1、聚合子查詢;2、含有 LIMIT 的子查詢;3、UNION 或 UNION ALL 子查詢;4、輸出字段中的子查詢;

如下面的語句,從執行計劃可以看出其條件作用于聚合子查詢之后:

SELECT?*
FROM???(SELECT?target,Count(*)FROM???operationGROUP??BY?target)?t
WHERE??target?=?'rm-xxxx'
+----+-------------+------------+-------+---------------+-------------+---------+-------+------+-------------+
|?id?|?select_type?|?table??????|?type??|?possible_keys?|?key?????????|?key_len?|?ref???|?rows?|?Extra???????|
+----+-------------+------------+-------+---------------+-------------+---------+-------+------+-------------+
|??1?|?PRIMARY?????|?<derived2>?|?ref???|?<auto_key0>???|?<auto_key0>?|?514?????|?const?|????2?|?Using?where?|
|??2?|?DERIVED?????|?operation??|?index?|?idx_4?????????|?idx_4???????|?519?????|?NULL??|???20?|?Using?index?|
+----+-------------+------------+-------+---------------+-------------+---------+-------+------+-------------+

確定從語義上查詢條件可以直接下推后,重寫如下:

SELECT?target,Count(*)
FROM???operation
WHERE??target?=?'rm-xxxx'
GROUP??BY?target

執行計劃變為:

+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+
|?id?|?select_type?|?table?|?type?|?possible_keys?|?key?|?key_len?|?ref?|?rows?|?Extra?|
+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+
|?1?|?SIMPLE?|?operation?|?ref?|?idx_4?|?idx_4?|?514?|?const?|?1?|?Using?where;?Using?index?|
+----+-------------+-----------+------+---------------+-------+---------+-------+------+--------------------+

關于 MySQL 外部條件不能下推的詳細解釋說明請參考以前文章:MySQL · 性能優化 · 條件下推到物化表 http://mysql.taobao.org/monthly/2016/07/08

7、提前縮小范圍

先上初始 SQL 語句:

SELECT?*
FROM???my_order?oLEFT?JOIN?my_userinfo?uON?o.uid?=?u.uidLEFT?JOIN?my_productinfo?pON?o.pid?=?p.pid
WHERE??(?o.display?=?0?)AND?(?o.ostaus?=?1?)
ORDER??BY?o.selltime?DESC
LIMIT??0,?15

該SQL語句原意是:先做一系列的左連接,然后排序取前15條記錄。從執行計劃也可以看出,最后一步估算排序記錄數為90萬,時間消耗為12秒。

+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+
|?id?|?select_type?|?table?|?type???|?possible_keys?|?key?????|?key_len?|?ref?????????????|?rows???|?Extra??????????????????????????????????????????????|
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+
|??1?|?SIMPLE??????|?o?????|?ALL????|?NULL??????????|?NULL????|?NULL????|?NULL????????????|?909119?|?Using?where;?Using?temporary;?Using?filesort???????|
|??1?|?SIMPLE??????|?u?????|?eq_ref?|?PRIMARY???????|?PRIMARY?|?4???????|?o.uid?|??????1?|?NULL???????????????????????????????????????????????|
|??1?|?SIMPLE??????|?p?????|?ALL????|?PRIMARY???????|?NULL????|?NULL????|?NULL????????????|??????6?|?Using?where;?Using?join?buffer?(Block?Nested?Loop)?|
+----+-------------+-------+--------+---------------+---------+---------+-----------------+--------+----------------------------------------------------+

由于最后 WHERE 條件以及排序均針對最左主表,因此可以先對 my_order 排序提前縮小數據量再做左連接。SQL 重寫后如下,執行時間縮小為1毫秒左右。

SELECT?*
FROM?(
SELECT?*
FROM???my_order?o
WHERE??(?o.display?=?0?)AND?(?o.ostaus?=?1?)
ORDER??BY?o.selltime?DESC
LIMIT??0,?15
)?oLEFT?JOIN?my_userinfo?uON?o.uid?=?u.uidLEFT?JOIN?my_productinfo?pON?o.pid?=?p.pid
ORDER?BY??o.selltime?DESC
limit?0,?15

再檢查執行計劃:子查詢物化后(select_type=DERIVED)參與 JOIN。雖然估算行掃描仍然為90萬,但是利用了索引以及 LIMIT 子句后,實際執行時間變得很小。

+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+
|?id?|?select_type?|?table??????|?type???|?possible_keys?|?key?????|?key_len?|?ref???|?rows???|?Extra??????????????????????????????????????????????|
+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+
|??1?|?PRIMARY?????|?<derived2>?|?ALL????|?NULL??????????|?NULL????|?NULL????|?NULL??|?????15?|?Using?temporary;?Using?filesort????????????????????|
|??1?|?PRIMARY?????|?u??????????|?eq_ref?|?PRIMARY???????|?PRIMARY?|?4???????|?o.uid?|??????1?|?NULL???????????????????????????????????????????????|
|??1?|?PRIMARY?????|?p??????????|?ALL????|?PRIMARY???????|?NULL????|?NULL????|?NULL??|??????6?|?Using?where;?Using?join?buffer?(Block?Nested?Loop)?|
|??2?|?DERIVED?????|?o??????????|?index??|?NULL??????????|?idx_1???|?5???????|?NULL??|?909112?|?Using?where????????????????????????????????????????|
+----+-------------+------------+--------+---------------+---------+---------+-------+--------+----------------------------------------------------+

8、中間結果集下推

再來看下面這個已經初步優化過的例子(左連接中的主表優先作用查詢條件):

SELECT????a.*,c.allocated
FROM??????(SELECT???resourceidFROM?????my_distribute?dWHERE????isdelete?=?0AND??????cusmanagercode?=?'1234567'ORDER?BY?salecode?limit?20)?a
LEFT?JOIN(SELECT???resourcesid,?sum(ifnull(allocation,?0)?*?12345)?allocatedFROM?????my_resourcesGROUP?BY?resourcesid)?c
ON????????a.resourceid?=?c.resourcesid

那么該語句還存在其它問題嗎?不難看出子查詢 c 是全表聚合查詢,在表數量特別大的情況下會導致整個語句的性能下降。

其實對于子查詢 c,左連接最后結果集只關心能和主表 resourceid 能匹配的數據。因此我們可以重寫語句如下,執行時間從原來的2秒下降到2毫秒。

SELECT????a.*,c.allocated
FROM??????(SELECT???resourceidFROM?????my_distribute?dWHERE????isdelete?=?0AND??????cusmanagercode?=?'1234567'ORDER?BY?salecode?limit?20)?a
LEFT?JOIN(SELECT???resourcesid,?sum(ifnull(allocation,?0)?*?12345)?allocatedFROM?????my_resources?r,(SELECT???resourceidFROM?????my_distribute?dWHERE????isdelete?=?0AND??????cusmanagercode?=?'1234567'ORDER?BY?salecode?limit?20)?aWHERE????r.resourcesid?=?a.resourcesidGROUP?BY?resourcesid)?c
ON????????a.resourceid?=?c.resourcesid

但是子查詢 a 在我們的SQL語句中出現了多次。這種寫法不僅存在額外的開銷,還使得整個語句顯的繁雜。使用 WITH 語句再次重寫:

WITH?a?AS
(SELECT???resourceidFROM?????my_distribute?dWHERE????isdelete?=?0AND??????cusmanagercode?=?'1234567'ORDER?BY?salecode?limit?20)
SELECT????a.*,c.allocated
FROM??????a
LEFT?JOIN(SELECT???resourcesid,?sum(ifnull(allocation,?0)?*?12345)?allocatedFROM?????my_resources?r,aWHERE????r.resourcesid?=?a.resourcesidGROUP?BY?resourcesid)?c
ON????????a.resourceid?=?c.resourcesid

總結

數據庫編譯器產生執行計劃,決定著SQL的實際執行方式。但是編譯器只是盡力服務,所有數據庫的編譯器都不是盡善盡美的。

上述提到的多數場景,在其它數據庫中也存在性能問題。了解數據庫編譯器的特性,才能避規其短處,寫出高性能的SQL語句。

程序員在設計數據模型以及編寫SQL語句時,要把算法的思想或意識帶進來。

編寫復雜SQL語句要養成使用 WITH 語句的習慣。簡潔且思路清晰的SQL語句也能減小數據庫的負擔 。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284306.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284306.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284306.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue根據菜單json數據動態按需加載路由Vue-router

每個菜單項對應一個頁面組件&#xff0c;根據菜單項動態按需加載路由 路由配置的正確寫法&#xff1a; /*router/index.js*/ import Vue from vue import Router from vue-router import url from ./url import store from ../storeVue.use(Router)const router new Router({/…

【ArcGIS微課1000例】0047:制圖表達(2)---河流漸變效果的實現

當我們在ArcMap中加載河流數據時,得到的效果往往如圖所示,僅僅是表示河流位置的線要素,既無法真實地反映河流的實際情況,同時在出圖的時候也遠沒有任何美化效果。 文章目錄 1.創建制圖表達2.添加幾何效果3.使用制圖規則4.使用制圖表達屬性覆蓋警告:這些操作會對您的數據庫…

操作系統思考 第二章 進程

第二章 進程 作者&#xff1a;Allen B. Downey 原文&#xff1a;Chapter 2 Processes 譯者&#xff1a;飛龍 協議&#xff1a;CC BY-NC-SA 4.0 2.1 抽象和虛擬化 在我們談論進程之前&#xff0c;我打算先定義幾個東西&#xff1a; 抽象&#xff08;Abstraction&#xff09;&…

1 句代碼,搞定 ASP.NET Core 綁定多個源到同一個類

問題有群友希望將路由中的信息綁定到一個Dto對象中&#xff1a;public class DDDDDto {[FromRoute(Name "collectionId")]public Guid collectionId { get; set; }[BindProperty(Name "relativeUrl")]public string relativeUrl { get; set; } }這樣就不用…

redux中間件的用法

1.定義 中間件就是一個函數&#xff0c;對store.dispatch方法進行了改造&#xff0c;在發出 Action 和執行 Reducer 這兩步之間&#xff0c;添加了其他功能。 2.舉例 日志中間件 import { applyMiddleware, createStore } from redux; import createLogger from redux-logger; …

設置git自動補全功能(windows版本)

目錄 下載 Git 的源代碼 在目錄中 git/contrib/completion/ 中找到 git-completion.bash 文件 將 git-completion.bash 文件改名為 .git-completion.bash 找到本機git安裝目錄 將.git-completion.bash文件復制到git安裝目錄下的etc文件夾 打開同目錄下的 bash.bashrc 文件&…

用Vue搭建一個應用盒子(二):datetime-picker

接著上次的進度&#xff0c;我們已經實現了一個todo-list。它已經具備了基本的功能&#xff0c;可以新建、編輯、刪除任務。但是美中不足的是&#xff0c;它的時間設定上只能通過輸入一段字符串來設定&#xff0c;很不社會。我們應該完成的效果是一個time-picker&#xff0c;日…

ArcGIS實驗教程——實驗四十八:ArcGIS制圖表達入門及案例教程

文章目錄 1. 制圖表達的概念1.1 什么是地圖表達1.2 使用制圖表達改善要素外觀1.3 制圖表達的優點2. 使用制圖表達2.1 創建制圖表達2.2 使用制圖表達來符號化圖層2.3 使用制圖表達規則3. 地圖表達實戰案例1.創建制圖表達2.添加幾何效果3.使用制圖規則4.使用制圖表達屬性覆蓋1. 制…

PAT (Advanced Level) 1070. Mooncake (25)

簡單貪心。先買性價比高的。 #include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<map> #include<stack> #include<queue> #include<string> #include<algorithm> using namespace std;doub…

[轉]Java 18 還未用上,Java 19 最新兩大特性曝光

鐵打的 Java&#xff0c;流水的版本。 不久前&#xff0c;Java 18 才正式發布&#xff0c;遵循 Oracle 六個月發一版本的頻率&#xff0c;Java 19 將在今年 9 月出爐。這不&#xff0c;還沒等眾多開發者用上 Java 18&#xff0c;關于 Java 19 最新的兩個目標功能就被披露了出…

文本生成器(bzoj 1030)

Description JSOI交給隊員ZYX一個任務&#xff0c;編制一個稱之為“文本生成器”的電腦軟件&#xff1a;該軟件的使用者是一些低幼人群&#xff0c;他們現在使用的是GW文本生成器v6版。該軟件可以隨機生成一些文章―――總是生成一篇長度固定且完全隨機的文章—— 也就是說&…

C# 值類型和引用類型講解

要了解值類型和引用類型&#xff0c;我們首先要知道堆和棧的區別&#xff1a;① 棧是編譯期間就分配好的內存空間&#xff0c;因此你的代碼中必須就棧的大小有明確的定義&#xff1b;堆是程序運行期間動態分配的內存空間&#xff0c;你可以根據程序的運行情況確定要分配的堆內存…

【ArcGIS微課1000例】0048:制圖表達(3)---水立方效果實現

本文講解ArcGIS中水立方效果的實現過程(制圖表達案例)。 文章目錄 一、效果展示二、制作步驟1. 創建數據庫及要素數據集2. 創建范圍3. 創建隨機點4. 創建泰森多邊形5. 創建制圖表達一、效果展示 基于制圖表達的思想,可以容易實現多種形式的水立方效果,例如: 怎么實現的呢…

Java中this與super的區別

2019獨角獸企業重金招聘Python工程師標準>>> this與super關鍵字在java中構造函數中的應用&#xff1a; ** super()函數 ** super()函數在子類構造函數中調用父類的構造函數時使用&#xff0c;而且必須要在構造函數的第一行&#xff0c;例如&#xff1a; class Ani…

EF選擇Mysql數據源

EF添加ADO.NET實體模型處直接選擇Mysql數據源 最近想到EF是連接多數據庫的orm框架&#xff0c;于是就想測試下。查了一堆網上資料后&#xff0c;測試連接mysql成功。步驟如下&#xff1a; 1、在你項目Model層中nuget安裝MySql.Data.Entity 如果沒安裝這個provider 就進行下面的…

JIRA簡介及基本概念

目錄 第一章 JIRA簡介 1.1 什么是JIRA 1.2 JIRA的主要功能 1.3 JIRA的主要特點 1.3.1 JIRA的優點 1.3.2 JIRA的缺點 1.4 相關版本 第二章 JIRA的基本概念 2.1 JIRA 中涉及的角色 2.1.1 管理人員 2.1.2 項目管理者 2.1.3 開發人員 2.1.4 測試人員 2.2 問題 2.2.1…

CodeChef Chef and Churu [分塊]

題意&#xff1a; 單點修改$a$ 詢問$a$的區間和$f$的區間和 原來普通計算機是這道題改編的吧... 對$f$分塊&#xff0c;預處理$c[i][j]$為塊i中$a_j$出現幾次&#xff0c;$O(NH(N))$&#xff0c;只要每個塊差分加上然后掃一遍就行了不用樹狀數組之類的 修改&#xff0c;整塊直接…

SkiaSharp 之 WPF 自繪 拖曳小球(案例版)

感謝各位大佬和粉絲的厚愛和關心( 催更)&#xff0c;我會再接再厲的&#xff0c;其實這也是督促自己的一種方式&#xff0c;非常感謝。剛寫了一篇萬字長文&#xff0c;自己也休養生息(低調發育)了一段時間&#xff0c;接下來來幾個小案例。拖曳小球WPF的拖曳效果&#xff0c;基…

Nodejs Guides(四)

EVENTS events模塊API實例 const EventEmitter require(events);class MyEmitter extends EventEmitter { } //EventListener 會按照監聽器注冊的順序同步地調用所有監聽器。 //所以需要確保事件的正確排序且避免競爭條件或邏輯錯誤。 //監聽器函數可以使用 setImmediate() 或…

[轉]常用自動化測試工具

1、Appium 官網&#xff1a;http://appium.io AppUI自動化測試 Appium 是一個移動端自動化測試開源工具&#xff0c;支持iOS 和Android 平臺&#xff0c;支持Python、Java 等語言&#xff0c;即同一套Java 或Python 腳本可以同時運行在iOS 和Android平臺&#xff0c;Appium 是…