DRDS分散式SQL引擎—執行計劃介紹

来源:https://www.cnblogs.com/aiaitie/archive/2018/07/12/9301000.html
-Advertisement-
Play Games

摘要: 本文著重介紹 DRDS 執行計劃中各個操作符的含義,以便用戶通過查詢計划了解 SQL 執行流程,從而有針對性的調優 SQL。 DRDS分散式SQL引擎 — 執行計劃介紹 前言 資料庫系統中,執行計劃是對 SQL 如何執行的形式化表示,往往由若幹關係操作符構成,用戶可以通過對應的 EXPLAI ...


摘要: 本文著重介紹 DRDS 執行計劃中各個操作符的含義,以便用戶通過查詢計划了解 SQL 執行流程,從而有針對性的調優 SQL。

DRDS分散式SQL引擎 — 執行計劃介紹

前言

資料庫系統中,執行計劃是對 SQL 如何執行的形式化表示,往往由若幹關係操作符構成,用戶可以通過對應的 EXPLAIN 命令查看,並通過執行計劃大致瞭解 SQL 的執行過程和執行方式,如全表掃描還是索引掃描,歸併連接還是哈希連接等。執行計劃可以為用戶進行 SQL 調優提供重要依據。

DRDS 執行計劃

與多數資料庫系統類似,DRDS 在處理 SQL 時,會通過優化器生成執行計劃,該執行計劃由關係操作符構成一個樹形結構,反映 DRDS 如何執行 SQL 語句;不同的是,DRDS 本身不存儲數據,更側重考慮分散式環境中的網路 IO 開銷,將運算下推到各個分庫(如 RDS/MySQL)執行,從而提升 SQL 執行效率。用戶可通過 EXPLAIN 命令查看 SQL 的執行計劃。

本文著重介紹 DRDS 執行計劃中各個操作符的含義,以便用戶通過查詢計划了解 SQL 執行流程,從而有針對性的調優 SQL。文中示例均基於如下表結構:

CREATE TABLE `sbtest1` (`id`  INT(10) UNSIGNED NOT NULL,`k`   INT(10) UNSIGNED NOT NULL DEFAULT '0',`c`   CHAR(120)        NOT NULL DEFAULT '',`pad` CHAR(60)         NOT NULL DEFAULT '',KEY `xid` (`id`),KEY `k_1` (`k`)) dbpartition BY HASH (`id`) tbpartition BY HASH (`id`) tbpartitions 4

先通過一個例子整體瞭解 DRDS 執行計劃的樹形結構。

mysql> explain select a.k, count(*) cnt from sbtest1 a, sbtest1 b where a.id = b.k and a.id > 1000 group by k having cnt > 1300 order by cnt limit 5, 10;+---------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                                      |+---------------------------------------------------------------------------------------------------------------------------------------------------+| TmpSort(sort="cnt ASC", offset=?2, fetch=?3)                                                                                                      ||   Filter(condition="cnt > ?1")                                                                                                                    ||     Aggregate(group="k", cnt="COUNT()")                                                                                                           ||       BKAJoin(id="id", k="k", c="c", pad="pad", id0="id0", k0="k0", c0="c0", pad0="pad0", condition="id = k", type="inner")                       ||         MergeSort(sort="k ASC")                                                                                                                   ||           LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?) ORDER BY `k`")        ||         UnionAll(concurrent=true)                                                                                                                 ||           LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE ((`k` > ?) AND (`k` IN ('?')))") || HitCache:false                                                                                                                                    |+---------------------------------------------------------------------------------------------------------------------------------------------------+9 rows in set (0.01 sec)

如上,DRDS EXPLAIN 的結果總體分為兩部分:執行計劃和其他信息。

  • 執行計劃

    執行計劃以縮進形式表示操作符之間的 "父-子" 關係。示例中,Filter 是 TmpSort 的子操作符,同時是 Aggregate 的父操作符。從真正執行的角度看,每個操作符均從其子操作符中獲取數據,經當前操作符處理,輸出給其父操作符。為方便理解,將以上執行計劃轉換為更加直觀的樹形結構:

  • 其他信息

    除執行計劃外,EXPLAIN 結果中還會有一些額外信息,目前僅有一項 `HitCache` 。需要說明的是,DRDS 會預設開啟 PlanCache 功能,`HitCache` 表示當前 SQL 是否命中 PlanCache。

    開啟 PlanCache 後,DRDS 會對 SQL 做參數化處理,參數化會將 SQL 中的大部分常量用 ? 替換,並構建一個參數列表。在執行計劃中的體現就是,LogicalView 的 sql 中會有 ? ,在部分操作符中會有類似 ?2 的字樣,這裡的 2 表示其在參數列表中的下標,後續會結合具體的例子進一步闡述。

EXPLAIN 語法

EXPLAIN 用於查看 SQL 語句的執行計劃,語法如下:

EXPLAIN explainable_stmtexplainable_stmt: {SELECT statement| DELETE statement| INSERT statement| REPLACE statement| UPDATE statement}

操作符介紹

本小節詳細介紹 DRDS 執行計劃中各個操作符的含義。

LogicalView

LogicalView 是從底層數據源獲取數據的操作符。從資料庫的角度來看,使用 TableScan 命名更符合常規,但考慮到 DRDS 本身不存儲數據,而是通過 SQL 從底層數據源獲取,因此,該操作符中會記錄下推的 SQL 語句和數據源信息,這更像一個 "視圖"。該 "視圖" 中的 SQL,通過優化器的下推,可能包含多種操作,如投影、過濾、聚合、排序、連接和子查詢等。

以下通過示例說明 EXPLAIN 中 LogicalView 的輸出信息及其含義:

mysql> explain select * From sbtest1 where id > 1000;+-----------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                          |+-----------------------------------------------------------------------------------------------------------------------+| UnionAll(concurrent=true)                                                                                             ||   LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") || HitCache:false                                                                                                        |+-----------------------------------------------------------------------------------------------------------------------+3 rows in set (0.00 sec)

LogicalView 的信息由三部分構成:

  • tables:底層數據源對應的表名,以 . 分割,其前是分庫對應的編號,其後是表名及其編號,對於連續的編號,會做簡寫,如 [000-127],表示表名編號從 000 到 127 的所有表。

  • shardCount:需要訪問的分表總數,該示例中會訪問從 000 到 127 共 128 張分表。

  • sql:下發至底層數據源的 SQL 模版。這裡顯示的並非真正下發的 SQL 語句,DRDS 在執行時會將表名替換為物理表名;另外,SQL 中的常量 10 被 ? 替換,這是因為 DRDS 預設開啟了 PlanCache 功能,對 SQL 做了參數化處理。

UnionAll

UnionAll 是 UNION ALL 對應的操作符,該操作符通常有多個輸入,表示將多個輸入的數據 UNION 在一起。以上示例中,LogicalView 之上的 UnionAll 表示將所有分表中的數據進行 UNION。

UnionAll 中的 concurrent 表示是否並行執行其子操作符,預設為 true。

UnionDistinct

與 UnionAll 類似,UnionDistinct 是 UNION DISTINCT 對應的操作符。如下:

mysql> explain select * From sbtest1 where id > 1000 union distinct select * From sbtest1 where id < 200;+-------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                            |+-------------------------------------------------------------------------------------------------------------------------+| UnionDistinct(concurrent=true)                                                                                          ||   UnionAll(concurrent=true)                                                                                             ||     LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") ||   UnionAll(concurrent=true)                                                                                             ||     LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` < ?)") || HitCache:false                                                                                                          |+-------------------------------------------------------------------------------------------------------------------------+6 rows in set (0.02 sec)

MergeSort

MergeSort,歸併排序操作符,通常有多個子操作符。DRDS 中實現了兩種排序:基於有序數據的歸併排序和對無序數據的記憶體排序。如下:

mysql> explain select *from sbtest1 where id > 1000 order by id limit 5,10;+---------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                                      |+---------------------------------------------------------------------------------------------------------------------------------------------------+| MergeSort(sort="id ASC", offset=?1, fetch=?2)                                                                                                     ||   LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?) ORDER BY `id` LIMIT (? + ?)") || HitCache:false                                                                                                                                    |+---------------------------------------------------------------------------------------------------------------------------------------------------+3 rows in set (0.00 sec)

MergeSort 操作符包含三部分內容:

  • sort:表示排序欄位以及排列順序,id ASC 表示按照 id 欄位遞增排序,DESC 表示遞減排序。

  • offset:表示獲取結果集時的偏移量,同樣由於對 SQL 做了參數化,示例中的 offst 表示為 ?1 ,其中 ? 表示這是一個動態參數,其後的數字對應參數列表的下標。示例中 SQL 對應的參數為 [1000, 5, 10],因此,?1 實際對應的值為 5

  • fetch:表示最多返回的數據行數。與 offset 類似,同樣是參數化的表示,實際對應的值為 10

Aggregate

Aggregate 是聚合操作符,通常包含兩部分內容:Group By 欄位和聚合函數。如下:

mysql> explain select k, count(*) from sbtest1 where id > 1000 group by k;+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                                                                |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Aggregate(group="k", count(*)="SUM(count(*))")                                                                                                                              ||   MergeSort(sort="k ASC")                                                                                                                                                   ||     LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, COUNT(*) AS `count(*)` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") || HitCache:true                                                                                                                                                               |+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+4 rows in set (0.00 sec)

Aggregate 包含兩部分內容:

  • group:表示 GROUP BY 欄位,示例中為 k 。

  • 聚合函數:= 前為聚合函數對應的輸出列名,其後為對應的計算方法。示例中 count(*)="SUM(count(*))" ,第一個 count(*) 對應輸出的列名,隨後的 SUM(count(*)) 表示對其輸入數據中的 count(*) 列進行 SUM 運算得到最終的 count(*)

由此可見,DRDS 將聚合操作分為兩部分,首先將聚合操作下推至底層數據源做局部聚合,最終在 DRDS 層面對局部聚合的結果做全局聚合。另外,DRDS 的最終聚合是基於排序做的,因此,會在優化器階段為其添加一個 Sort 子操作符,而 Sort 操作符又進一步通過下推 Sort 轉換為 MergeSort

再來看一個 AVG 聚合函數的例子,如下:

mysql> explain select k, avg(id) avg_id from sbtest1 where id > 1000 group by k;+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN|+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Project(k="k", avg_id="sum_pushed_sum / sum_pushed_count")||   Aggregate(group="k", sum_pushed_sum="SUM(pushed_sum)", sum_pushed_count="SUM(pushed_count)")||     MergeSort(sort="k ASC")||       LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, SUM(`id`) AS `pushed_sum`, COUNT(`id`) AS `pushed_count` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`")|| HitCache:false|+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+5 rows in set (0.01 sec)

DRDS 會將 AVG 聚合函數轉換為 SUM / COUNT,再分別根據 SUM 和 COUNT 的下推規則,將其轉換為局部聚合和全局聚合。用戶可自行嘗試瞭解其他聚合函數的執行計劃。

註意:DRDS 會將 DISTINCT 操作轉換為 GROUP 操作,如下:

mysql> explain select distinct k from sbtest1 where id > 1000;+-----------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                                        |+-----------------------------------------------------------------------------------------------------------------------------------------------------+| Aggregate(group="k")                                                                                                                                ||   MergeSort(sort="k ASC")                                                                                                                           ||     LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") || HitCache:false                                                                                                                                      |+-----------------------------------------------------------------------------------------------------------------------------------------------------+4 rows in set (0.02 sec)

TmpSort

TmpSort,表示在記憶體中對數據進行排序。與 MergeSort 的區別在於,MergeSort 可以有多個子操作符,且每個子操作符返回的數據都已經排序。TmpSort 僅有一個子操作符。

TmpSort 對應的查詢計劃信息與 MergeSort 一致,請參考 MergeSort。

Project

Project 表示投影操作,即從輸入數據中選擇部分列輸出,或者對某些列進行轉換(通過函數或者表達式計算)後輸出,當然,也可以包含常量。以上 AVG 的示例中,最頂層就是一個 Project,其輸出 k 和 sum_pushed_sum / sum_pushed_count ,後者對應的列名為 avg_id 。

mysql> explain select '你好, DRDS', 1 / 2, CURTIME();+-------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                        |+-------------------------------------------------------------------------------------+| Project(你好, DRDS="_UTF-16'你好, DRDS'", 1 / 2="1 / 2", CURTIME()="CURTIME()") ||                                                                                     || HitCache:false                                                                      |+-------------------------------------------------------------------------------------+3 rows in set (0.00 sec)

可見,Project 的計劃中包括每列的列名及其對應的列、值、函數或者表達式。

Filter

Filter 表示過濾操作,其中包含一些過濾條件。該操作符對輸入數據進行過濾,若滿足條件,則輸出,否則丟棄。如下是一個較複雜的例子,包含了以上介紹的大部分操作符。

mysql> explain select k, avg(id) avg_id from sbtest1 where id > 1000 group by k having avg_id > 1300;+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN  |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| Filter(condition="avg_id > ?1")  ||   Project(k="k", avg_id="sum_pushed_sum / sum_pushed_count")  ||     Aggregate(group="k", sum_pushed_sum="SUM(pushed_sum)", sum_pushed_count="SUM(pushed_count)")  ||       MergeSort(sort="k ASC")  ||         LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k`, SUM(`id`) AS `pushed_sum`, COUNT(`id`) AS `pushed_count` FROM `sbtest1` WHERE (`id` > ?) GROUP BY `k` ORDER BY `k`") || HitCache:false  |+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+6 rows in set (0.01 sec)

在以上 AVG 示例的 SQL 基礎上添加了having avg_id > 1300 ,執行計劃最上層添加了一個 Filter 操作符,用於過濾所有滿足 avg_id > 1300 的數據。

有讀者可能會問,WHERE 中的條件為什麼沒有對應的 Filter 操作符呢?在 DRDS 優化器的某個階段,WHERE 條件的 Filter 操作符的確是存在的,只是最終將其下推到了 LogiacalView 中,因此可以在 LogicalView 的 sql 中看到 id > 1000 。

NlJoin

NlJoin,表示 NestLoop Join 操作符,即使用 NestLoop 方法進行兩表 Join。DRDS 中實現了兩種 JOIN 策略:NlJoin 和 BKAJoin,後者表示 Batched Key Access Join,批量鍵值查詢,會從左表取一批數據,構建一個 IN 條件拼接在訪問右表的 SQL 中,從右表一次獲取一批數據。

mysql> explain select a.* from sbtest1 a, sbtest1 b where a.id = b.k and a.id > 1000;+----------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                               |+----------------------------------------------------------------------------------------------------------------------------+| Project(id="id", k="k", c="c", pad="pad")                                                                                  ||   NlJoin(id="id", k="k", c="c", pad="pad", k0="k0", condition="id = k", type="inner")                                      ||     UnionAll(concurrent=true)                                                                                              ||       LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)")  ||     UnionAll(concurrent=true)                                                                                              ||       LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT `k` FROM `sbtest1` WHERE (`k` > ?)") || HitCache:false                                                                                                             |+----------------------------------------------------------------------------------------------------------------------------+7 rows in set (0.03 sec)

NlJOIN 的計劃包括三部分內容:

  • 輸出列信息:輸出的列名,示例中的 JOIN 會輸出 5 列 id="id", k="k", c="c", pad="pad", k0="k0" 。

  • contition:連接條件,示例中連接條件為 id = k 。

  • type:連接類型,示例中是 INNER JOIN,因此其連接類型為 inner 。

BKAJoin

BKAJoin,Batched Key Access Join,表示通過批量鍵值查詢的方式進行 JOIN,即從左表取一批數據,構建一個 IN 條件拼接在訪問右表的 SQL 中,從右表一次獲取一批數據進行 JOIN。

mysql> explain select a.* from sbtest1 a, sbtest1 b where a.id = b.k order by a.id;+-------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                  |+-------------------------------------------------------------------------------------------------------------------------------+| Project(id="id", k="k", c="c", pad="pad")                                                                                     ||   BKAJoin(id="id", k="k", c="c", pad="pad", id0="id0", k0="k0", c0="c0", pad0="pad0", condition="id = k", type="inner")       ||     MergeSort(sort="id ASC")                                                                                                  ||       LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` ORDER BY `id`")        ||     UnionAll(concurrent=true)                                                                                                 ||       LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`k` IN ('?'))") || HitCache:false                                                                                                                |+-------------------------------------------------------------------------------------------------------------------------------+7 rows in set (0.01 sec)

BKAJoin 的計劃內容與 NlJoin 相同,這兩個操作符命名不同,旨在告知執行器以何種方法執行 JOIN 操作。另外,以上執行計劃中右表的 LogicalView 中 k IN ('?') 是優化器構建出來的對右表的IN查詢模板。

LogicalModifyView

如上文介紹,LogicalView 表示從底層數據源獲取數據的操作符,與之對應的,LogicalModifyView 表示對底層數據源的修改操作符,其中也會記錄一個 SQL 語句,該 SQL 可能是 INSERT、UPDATE 或者 DELETE。

mysql> explain update sbtest1 set c='Hello, DRDS' where id > 1000;+--------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                   |+--------------------------------------------------------------------------------------------------------------------------------+| LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="UPDATE `sbtest1` SET `c` = ? WHERE (`id` > ?)") || HitCache:false                                                                                                                 |+--------------------------------------------------------------------------------------------------------------------------------+2 rows in set (0.03 sec)mysql> explain delete from sbtest1 where id > 1000;+-------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                            |+-------------------------------------------------------------------------------------------------------------------------+| LogicalModifyView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="DELETE FROM `sbtest1` WHERE (`id` > ?)") || HitCache:false                                                                                                          |+-------------------------------------------------------------------------------------------------------------------------+2 rows in set (0.03 sec)

LogicalModifyView 查詢計劃的內容與 LogicalView 類似,包括下發的物理分表,分表數以及 SQL 模版。同樣,由於開啟了 PlanCache,對 SQL 做了參數化處理,SQL 模版中的常量會用 ? 替換。

PhyTableOperation

PhyTableOperation 表示對某個物理分表執行一個操作。該操作符目前僅用於 INSERT INTO ... VALUES ...。

mysql> explain insert into sbtest1 values(1, 1, '1', '1'),(2, 2, '2', '2');+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                                                                                                                 |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+| PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_001]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_001`,1,1,1,1") || PhyTableOperation(tables="SYSBENCH_CORONADB_1526954857179TGMMSYSBENCH_CORONADB_VGOC_0000_RDS.[sbtest1_002]", sql="INSERT INTO ? (`id`, `k`, `c`, `pad`) VALUES(?, ?, ?, ?)", params="`sbtest1_002`,2,2,2,2") ||                                                                                                                                                                                                              || HitCache:false                                                                                                                                                                                               |+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+4 rows in set (0.00 sec)

示例中,INSERT 插入兩行數據,每行數據對應一個 PhyTableOperation 操作符,PhyTableOperation 操作符的內容包括三部分:

  • tables:物理表名,僅有唯一一個物理表名。

  • sql:SQL 模版,該 SQL 模版中表名和常量均被參數化,用 ? 替換,對應的參數在隨後的 params 中給出。

  • params:SQL 模版對應的參數,包括表名和常量。

其他信息

HitCache

DRDS 會預設開啟 PlanCache 功能,HitCache 用於告知用戶當前查詢是否命中 PlanCache。如下,第一次運行 HitCache 為 false,第二次運行為 true。

mysql> explain select * From sbtest1 where id > 1000;+-----------------------------------------------------------------------------------------------------------------------+| LOGICAL PLAN                                                                                                          |+-----------------------------------------------------------------------------------------------------------------------+| UnionAll(concurrent=true)                                                                                             ||   LogicalView(tables="[0000-0031].sbtest1_[000-127]", shardCount=128, sql="SELECT * FROM `sbtest1` WHERE (`id` > ?)") || HitCache:false                                                                                                        |+-----------------------------------------------------------------------------------------------------------------------+3 rows in&n

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 假設原用戶名老王,已刪除,但是cmd後路徑還是C:\Users\老王>,這與現在用戶laowng不一致了需改為C:\Users\laowang>。 1.先新建一個管理員賬戶laowang,然後登陸laowang這個賬戶; 2.重命名 c:\Users\老王 為 c:\Users\laowang; 3 ...
  • linux ping之後一直執行,那麼怎麼退出呢? 1、按Ctrl + C鍵中斷ping命令運行即可。 2、使用ping命令的-c參數,指明發送數據報文的次數,如下圖所示,只發送4次報文,發送完畢自動退出 ...
  • 1.查詢數據表的所有列: select * from 表名; 程式員正常用法:select 列名,列名... form 表名; 2.起別名: select 列名 [AS 別名],列名 別名...from 表名; --正常SELECT ename as 員工姓名,sal From emp; 別名是關鍵 ...
  • 表level,其主鍵為lid 1.select max(id) from table 查詢語句:SELECT MAX(lid) FROM LEVEL 返回插入主鍵 2.select LAST_INSERT_ID(id) from table 查詢語句:SELECT LAST_INSERT_ID(li ...
  • 目錄 一、概述 二、工作機制 三、安裝 1、前提概述 2、軟體下載 3、安裝步驟 四、Sqoop的基本命令 基本操作 示例 五、Sqoop的數據導入 1、從RDBMS導入到HDFS中 2、把MySQL資料庫中的表數據導入到Hive中 3、把MySQL資料庫中的表數據導入到hbase 目錄 一、概述 ...
  • 一、從官網下載mysql-5.7.22-winx64.zip壓縮文件,解壓到自定義目錄。 二、將mysql安裝目錄的下的bin目錄 添加到系統path環境變數。 三、配置my.ini 文件,放置於mysql的安裝目錄之內。文件內容如下: 說明: basedir為mysql安裝目錄,datadir為數 ...
  • 前言:我用的是wafer2 node.解決方案 下麵連接有環境配置及搭建流程(https://github.com/tencentyun/wafer2-quickstart-nodejs) ,連接是官方的可以點擊 一、配置mysql 資料庫連接參數 打開 server下麵的config.js use ...
  • 資料庫sql優化總結-百萬級資料庫優化方案+數據分析 有三張百萬級數據表 知識點表(ex_subject_point)9,316條數據 試題表(ex_question_junior)2,159,519條數據 有45個欄位 知識點試題關係表(ex_question_r_knowledge)3,156,... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...