搜尋
首頁資料庫SQL記錄 慢SQL優化實戰

記錄 慢SQL優化實戰

Dec 25, 2020 pm 05:23 PM
mysqlsql

sql教學介紹sql慢查詢的最佳化

記錄 慢SQL優化實戰

#推薦(免費):sql教學

#一、有問題

##經過sql慢查詢的最佳化,我們系統中發現了以下幾種類型的問題:

1.未建索引:整张表没有建索引;2.索引未命中:有索引,但是部分查询条件下索引未命中;3.搜索了额外的非必要字段,导致回表;4.排序,聚合导致慢查询;5.相同内容多次查询数据库;6.未消限制搜索范围或者限制的搜索范围在预期之外,导致全部扫描;

#二、解決方案

1.优化索引,增加或者修改当前的索引;         

2.重写sql;3.利用redis缓存,减少查询次数;4.增加条件,避免非必要查询;5.增加条件,减少查询范围;

三、案例分析

(一)藥材搜尋介面

完整sql語句在附錄,為方便閱讀和脫敏,部分常用欄位採用中文。

這兒主要講一下我們拿到Sql語句後的整個分析過程,思考邏輯,然後進行調整的過程和最後解決的辦法。

提供給大家一些借鑒,也希望大家能夠提出更好的建議。

這個sql語句要求是根據醫生搜尋的拼音或中文,進行模糊查詢,找到藥材,然後根據醫生選擇的藥庫,找出下面的供應商,然後根據供應商,進行藥材匹配,排除掉供應商沒有的藥材,然後根據真名在前,別名在後,完全匹配在前,部分匹配在後,附加醫生最近半年的使用習慣,把藥材排序出來。最後把不同名稱的同一味藥聚合起來,以真名(另名)的形式展現。

1.分析sql

    (1)14-8
第14排,id為8的explain結果分析:

①Explain
8,DERIVED,ssof,range,"ix_district,ix_供应商id",ix_district,8,NULL,18,Using where; Using index; Using temporary
②Sql
SELECT DISTINCT (ssof.供应商id) AS 供应商id FROM  药库供应商关系表 AS ssof  WHERE ssof.药库id IN (  1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22, 24, 25, 26, 27, 31, 33)  AND ssof.药方剂型id IN (1)
③索引
PRIMARY KEY (`id`),    UNIQUE KEY `ix_district` (        `药库id`, `药方剂型id`, `供应商id`    ) USING BTREE,KEY `ix_供应商id` (`供应商id`) USING BTREE
④分析
#使用了索引,建立了臨時表,這個地方索引已經完全覆蓋了,但是還有回表操作。

原因是用in,這個導致了回表。如果in可以被mysql 自動最佳化為等於,就不會回表。如果無法優化,就回表。

臨時表是因為有distinct,所以無法避免。

同時使用in要注意,如果裡面的數值數量比較多​​,有幾萬個。即使區分度高,就會導致索引失效,這種情況需要多次分批查詢。

2. 12-7

    (1)Explain
7,DERIVED,<derived8>,ALL,NULL,NULL,NULL,NULL,18,Using temporary; Using filesort</derived8>
    (2)Sql
INNER JOIN (上面14-8临时表) tp ON tp.供应商id= ms.供应商id
    #( 3)索引

    (4)分析
對臨時表操作,無索引,並用了檔案排序。

這一部分是對臨時表和藥材表進行關聯操作的一部分,有文件排序是因為需要對藥材表id進行group by 導致的。

1、預設情況下,mysql在使用group by之後,會產生臨時表,而後進行排序(此處排序預設是快排),這會消耗的效能。

2、group by本質是先分組後排序【而不是先排序後分組】。

3、group by column 預設會依照column分組, 然後依照column升序排列;  group by column order by null 則預設依照column分組,然後依照標的主鍵ID升序排列。

3. 13-7

    (1)Explain
7,DERIVED,ms,ref,"ix_title,idx_audit,idx_mutiy",idx_mutiy,5,"tp.供应商id,const",172,NULL
    (2)Sql
SELECT ms.药材表id, max(ms.audit) AS audit, max(ms.price) AS price, max(ms.market_price) AS market_price,max(ms.is_granule) AS is_granule,max(ms.is_decoct) AS is_decoct, max(ms.is_slice) AS is_slice,max(ms.is_cream) AS is_cream, max(ms.is_extract) AS is_extract,max(ms.is_cream_granule) AS is_cream_granule, max(ms.is_extract_granule) AS is_extract_granule,max(ms.is_drychip) AS is_drychip,            max(ms.is_pill) AS is_pill,max(ms.is_powder) AS is_powder, max(ms.is_bolus) AS is_bolus FROM 供应商药材表 AS ms INNER JOIN (                SELECT                    DISTINCT (ssof.供应商id) AS 供应商id                FROM                    药库供应商关系表 AS ssof WHERE  ssof.药库id IN (  1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22, 24, 25, 26, 27, 31, 33 ) AND ssof.药方剂型id IN (1) ) tp ON tp.供应商id= ms.供应商id WHERE  ms.audit = 1  GROUP BY  ms.药材表id
    #( 3)索引
   KEY `idx_mutiy` (`供应商id`, `audit`, `药材表id`)
    (4)分析
#命中了索引,表間連接使用了供應商id,建立索引的順序是供應商id ,where條件中audit,Group by 條件藥材表id。

這部分暫時不需要更改。

4.10-6

    (1)Explain
6,DERIVED,r,range,"PRIMARY,id,idx_timeline,idx_did_timeline,idx_did_isdel_statuspay_timecreate_payorderid,idx_did_statuspay_ischecked_isdel",idx_did_timeline,8,NULL,546,Using where; Using index; Using temporary; Using filesort
    (2)Sql
  • #
SELECT 
       count(*) AS total, 
       rc.i AS m药材表id 
     FROM 
        处方药材表 AS rc 
        INNER JOIN 药方表AS r ON r.id = rc.药方表_id 
     WHERE 
         r.did = 40 
         AND r.timeline > 1576115196 
         AND rc.type_id in (1, 3) 
         GROUP BY 
    rc.i
    (3)索引
KEY `idx_did_timeline` (`did`, `timeline`),
    (4)分析
驅動表與被驅動表,小表驅動大表。

先了解在join連接時哪個表是驅動表,哪個表是被驅動表:

1.當使用left join時,左表是驅動表,右表是被驅動表;

2.當使用right join時,右表時驅動表,左表是驅動表;

3.當使用join時,mysql會選擇資料量比較小的表作為驅動表,大表作為被驅動表;

4. in後跟的是驅動表, exists前面的是驅動表;

5. 11-6

    (1)Explain
6,DERIVED,rc,ref,"orderid_药材表,药方表_id",药方表_id,5,r.id,3,Using where
    (2)Sql
同上

    #(3)索引
  KEY `idx_药方表_id` (`药方表_id`, `type_id`) USING BTREE,
    (4)分析
索引的順序沒有問題,仍舊是in 導致了回表。

6.8-5

  • (1)Explain
5,UNION,malias,ALL,id_tid,NULL,NULL,NULL,4978,Using where
  • (2)Sql
 SELECT 
      mb.id, 
      mb.sort_id, 
      mb.title, 
      mb.py, 
      mb.unit, 
      mb.weight, 
      mb.tid, 
      mb.amount_max, 
      mb.poisonous, 
      mb.is_auxiliary, 
      mb.is_auxiliary_free, 
      mb.is_difficult_powder, 
      mb.brief, 
      mb.is_fixed_recipe, 
      ASE WHEN malias.py = 'GC' THEN malias.title ELSE CASE WHEN malias.title = 'GC' THEN malias.title ELSE '' END END AS atitle, 
      alias.py AS apy, 
      CASE WHEN malias.py = 'GC' THEN 2 ELSE CASE WHEN malias.title = 'GC' THEN 2 ELSE 1 END END AS ttid 
 FROM 
      药材表 AS mb 
      LEFT JOIN 药材表 AS malias ON malias.tid = mb.id 
WHERE 
      alias.title LIKE '%GC%' 
      OR malias.py LIKE '%GC%'
  • (3)索引
KEY `id_tid` (`tid`) USING BTREE,
  • (4)分析

因为like是左右like,无法建立索引,所以只能建tid。Type是all,遍历全表以找到匹配的行,左右表大小一样,估算的找到所需的记录所需要读取的行数有4978。这个因为是like的缘故,无法优化,这个语句并没有走索引,药材表 AS mb FORCE INDEX (id_tid) 改为强制索引,读取的行数减少了700行。

7.9-5

  • (1)Explain
5,UNION,mb,eq_ref,"PRIMARY,ix_id",PRIMARY,4,malias.tid,1,NULL
  • (2)Sql

同上

  • (3)索引
PRIMARY KEY (`id`) USING BTREE,
  • (4)分析

走了主键索引,行数也少,通过。

8.7-4

  • (1)Explain
4,DERIVED,mb,ALL,id_tid,NULL,NULL,NULL,4978,Using where
  • (2)Sql

    SELECT 
       mb.id, 
       mb.sort_id, 
       mb.title, 
       mb.py, 
       mb.unit, 
       mb.weight, 
       mb.tid, 
       mb.amount_max, 
       mb.poisonous, 
       mb.is_auxiliary, 
       mb.is_auxiliary_free, 
       mb.is_difficult_powder, 
       mb.brief, 
       mb.is_fixed_recipe, 
       '' AS atitle, 
       '' AS apy, 
       CASE WHEN mb.py = 'GC' THEN 3 ELSE CASE WHEN mb.title = 'GC' THEN 3 ELSE 1 END END AS ttid 
    FROM 
       药材表 AS mb 
      WHERE 
       mb.tid = 0 
       AND (
           mb.title LIKE '%GC%' 
           OR mb.py LIKE '%GC%'
                                )
  • (3)索引

KEY `id_tid` (`tid`) USING BTREE,
  • (4)分析

    tid int(11) NOT NULL DEFAULT ‘0’ COMMENT ‘真名药品的id’,

他也是like,这个没法优化。

9.6-3

  • (1)Explain
3,DERIVED,<derived4>,ALL,NULL,NULL,NULL,NULL,9154,Using filesort</derived4>
  • (2)Sql

    UNION ALL

  • (3)索引

  • (4)分析

就是把真名搜索结果和别人搜索结果合并。避免用or连接,加快速度 形成一个munion的表,初步完成药材搜索,接下去就是排序。

这一个进行了2次查询,然后用union连接,可以考虑合并为一次查询。用case when进行区分,计算出权重。

这边是一个优化点。

10.4-2

  • (1)Explain
2,DERIVED,<derived3>,ALL,NULL,NULL,NULL,NULL,9154,NULL</derived3>
  • (2)Sql

    SELECT 
       munion.id, 
       munion.sort_id, 
       case when length(
         trim(
              group_concat(munion.atitle SEPARATOR ' ')
                        )
                    )> 0 then concat(
                        munion.title, 
                        '(', 
                        trim(
                            group_concat(munion.atitle SEPARATOR ' ')
                        ), 
                        ')'
                    ) else munion.title end as title, 
          munion.py, 
          munion.unit, 
          munion.weight, 
          munion.tid, 
          munion.amount_max, 
          munion.poisonous, 
          munion.is_auxiliary, 
          munion.is_auxiliary_free, 
          munion.is_difficult_powder, 
          munion.brief, 
          munion.is_fixed_recipe, 
          --  trim( group_concat( munion.atitle SEPARATOR ' ' ) ) AS atitle,
                    ##  --  
           trim(
                 group_concat(munion.apy SEPARATOR ' ')
                 ) AS apy, 
             ##   
               max(ttid) * 100000 + id AS ttid 
         FROM 
                munion <derived4>
             GROUP BY 
                id -- 全部实名药材 结束##</derived4>
  • (3)索引

  • (4)分析

这里全部在临时表中搜索了。

11.5-2

  • (1)Explain
2,DERIVED,<derived6>,ref,<auto_key0>,<auto_key0>,5,m.id,10,NULL</auto_key0></auto_key0></derived6>
  • (2)Sql
Select fields from 全部实名药材表 as m  LEFT JOIN ( 个人使用药材统计表 ) p ON m.id = p.m药材表id
  • (3)索引

  • (4)分析

2张虚拟表left join

使用了优化器为派生表生成的索引

这边比较浪费性能,每次查询,都要对医生历史开方记录进行统计,并且统计还是几张大表计算后的结果。但是如果只是sql优化,这边暂时无法优化。

12.2-1

  • (1)Explain
1,PRIMARY,<derived7>,ALL,NULL,NULL,NULL,NULL,3096,Using where; Using temporary; Using filesort</derived7>
  • (2)Sql

  • (3)索引

  • (4)分析

临时表操作

13.3-1

  • (1)Explain
1,PRIMARY,<derived2>,ref,<auto_key0>,<auto_key0>,4,msu.药材表id,29,NULL</auto_key0></auto_key0></derived2>
  • (2)Sql

  • (3)索引

  • (4)分析

临时表操作

14.null

  • (1)Explain
NULL,UNION RESULT,"<union4>",ALL,NULL,NULL,NULL,NULL,NULL,Using temporary</union4>
  • (2)Sql

  • (3)索引

  • (4)分析

临时表

(二)优化sql

上面我们只做索引的优化,遵循的原则是:

1.最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。2.=和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式。3.尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录。4.索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)。5.尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

查询优化神器 - explain命令

关于explain命令相信大家并不陌生,具体用法和字段含义可以参考官网explain-output,这里需要强调rows是核心指标,绝大部分rows小的语句执行一定很快(有例外,下面会讲到)。所以优化语句基本上都是在优化rows。

化基本步骤:

0.先运行看看是否真的很慢,注意设置SQL_NO_CACHE1.where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高;2.explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询);3.order by limit 形式的sql语句让排序的表优先查;4.了解业务方使用场景;5.加索引时参照建索引的几大原则;6.观察结果,不符合预期继续从0分析;

上面已经详细的分析了每一个步骤,根据上面的sql,去除union操作, 增加索引。可以看出,优化后虽然有所改善。但是距离我们的希望还有很大距离,但是光做sql优化,感觉也没有多少改进空间,所以决定从其他方面解决。

(三)拆分sql

由于速度还是不领人满意,尤其是个人用药情况统计,其实没必要每次都全部统计一次,再要优化,只靠修改索引应该是不行的了,所以考虑使用缓存。

接下来是修改php代码,把全部sql语句拆分,然后再组装。

  • (1)搜索真名,别名(缓存)
SELECT  mb.id,  mb.sort_id,  mb.title,  mb.py,  mb.unit,  mb.weight,  mb.tid,  mb.amount_max,  mb.poisonous,  mb.is_auxiliary,  mb.is_auxiliary_free,  mb.is_difficult_powder,  mb.brief,  mb.is_fixed_recipe,  IFNULL(group_concat(malias.title),'') atitle,  IFNULL(group_concat(malias.py),'') apy  FROM  药材表 AS mb  LEFT JOIN 药材表 AS malias ON malias.tid = mb.id  WHERE  mb.tid = 0  AND (  malias.title LIKE '%GC%'  OR malias.py LIKE '%GC%'  or mb.title LIKE '%GC%'  OR mb.py LIKE '%GC%'  )  group by  mb.id

  • (2)如果命中有药材
①排序

真名在前,别名在后,完全匹配在前,部分匹配在后

//对搜索结果进行处理,增加权重
②对供应商药材搜索
SELECT ms.药材表id, max( ms.audit ) AS audit, max( ms.price ) AS price, max( ms.market_price ) AS market_price, max( ms.is_granule ) AS is_granule, max( ms.is_decoct ) AS is_decoct, max( ms.is_slice ) AS is_slice, max( ms.is_cream ) AS is_cream, max( ms.is_extract ) AS is_extract, max( ms.is_cream_granule) AS is_cream_granule, max( ms.is_extract_granule) AS is_extract_granule, max( ms.is_drychip ) AS is_drychip, max( ms.is_pill ) AS is_pill, max( ms.is_powder ) AS is_powder, max( ms.is_bolus ) AS is_bolus  FROM 供应商药材表 AS ms WHERE ms.audit = 1 AND ms.供应商idin (  SELECT DISTINCT  ( ssof.供应商id) AS 供应商id FROM  药库供应商关系表 AS ssof  WHERE  ssof.药库id IN ( 1,2,8,9,10,11,12,13,14,15,17,22,24,25,26,27,31,33 )  AND ssof.药方剂型id IN (1) ) AND ms.药材表id IN ( 78,205,206,207,208,209,334,356,397,416,584,652,988,3001,3200,3248,3521,3522,3599,3610,3624,4395,4396,4397,4398,4399,4400,4401,4402,4403,4404,4405,4406,4407,4408,5704,5705,5706,5739,5740,5741,5742,5743,6265,6266,6267,6268,6514,6515,6516,6517,6518,6742,6743 ) AND ms.is_slice = 1  GROUP BY ms.药材表id

③拿医生历史开方药材用量数据(缓存)
SELECT  count( * ) AS total,  rc.i AS 药材表id FROM  处方药材表 AS rc  INNER JOIN 药方表AS r ON r.id = rc.药方表_id WHERE  r.did = 40  AND r.timeline > 1576116927  AND rc.type_id in (1,3) GROUP BY  rc.i

④  装配及排序微调

  • (3)小结

运行速度,对于开方量不是特别多的医生来说,两者速度都是0.1秒左右.但是如果碰到开方量大的医生,优化后的sql速度比较稳定,能始终维持在0.1秒左右,优化前的sql速度会超过0.2秒.速度提升约一倍以上。

最后对搜索结果和未优化前的搜索结果进行比对,结果数量和顺序完全一致.本次优化结束。

四、附录:

SELECT sql_no_cache 
    *FROM
    (
        -- mbu start##        SELECT
            m.*,
            ifnull(p.total, 0) AS total        FROM
            (
                --全部实名药材
开始
##SELECT
       munion.id,
       munion.sort_id,
       case when length(
        trim(
              group_concat(munion.atitle SEPARATOR ' ')
                 )
             )> 0 then concat(
           munion.title,
          '(',
      trim(
             group_concat(munion.atitle SEPARATOR ' ')
              ),
                ')'
             ) else munion.title end as title,
        munion.py,
        munion.unit,
        munion.weight,
        munion.tid,
        munion.amount_max,
        munion.poisonous,
        munion.is_auxiliary,
        munion.is_auxiliary_free,
        munion.is_difficult_powder,
        munion.brief,
        munion.is_fixed_recipe,
        --  trim( group_concat( munion.atitle SEPARATOR ' ' ) ) AS atitle,##        --  trim( group_concat( munion.apy SEPARATOR  ' ' ) ) AS apy,##              max(ttid) * 100000 + id AS ttid           FROM
              (
                -- #union start
联合查找,得到全部药材
##  (
       SELECT
              mb.id,
              mb.sort_id,
              mb.title,
              mb.py,
              mb.unit,
              mb.weight,
              mb.tid,
              mb.amount_max,
              mb.poisonous,
              mb.is_auxiliary,
              mb.is_auxiliary_free,
              mb.is_difficult_powder,
              mb.brief,
              mb.is_fixed_recipe,
              '' AS atitle,
              '' AS apy,
              CASE WHEN mb.py = 'GC' THEN 3 ELSE CASE WHEN mb.title = 'GC' THEN 3 ELSE 1 END END AS ttid               FROM
                 药材表 AS mb                     WHERE
                         mb.tid = 0
                       AND (
                              mb.title LIKE '%GC%'
                              OR mb.py LIKE '%GC%'
                                )
                        ) --真名药材

结束
## UNION ALL
    (
      SELECT
            mb.id,
            mb.sort_id,
            mb.title,
            mb.py,
            mb.unit,
            mb.weight,
            mb.tid,
            mb.amount_max,
            mb.poisonous,
            mb.is_auxiliary,
            mb.is_auxiliary_free,
            mb.is_difficult_powder,
            mb.brief,
            mb.is_fixed_recipe,
            CASE WHEN malias.py = 'GC' THEN malias.title ELSE CASE WHEN malias.title = 'GC' THEN malias.title ELSE '' END END AS atitle,
            malias.py AS apy,
            CASE WHEN malias.py = 'GC' THEN 2 ELSE CASE WHEN malias.title = 'GC' THEN 2 ELSE 1 END END AS ttid          FROM
                药材表 AS mb                LEFT JOIN 药材表 AS malias ON malias.tid = mb.id          WHERE
                malias.title LIKE '%GC%'
                OR malias.py LIKE '%GC%'
                      ) --其他药材结束
##                 -- #union end##                ) munion                GROUP BY
                    id --全部实名药材

结束
##                    ) m            LEFT JOIN (
                --个人使用药材统计

开始
##    SELECT
          count(*) AS total,
          rc.i AS m药材表id     FROM
           处方药材表 AS rc           INNER JOIN 药方表AS r ON r.id = rc.药方表_id      WHERE
           r.did = 40
            AND r.timeline > 1576115196
            AND rc.type_id in (1, 3)
       GROUP BY
              rc.i --个人使用药材统计

结束
##           ) p ON m.id = p.m药材表id -- mbu end ##            ) mbu    INNER JOIN (
        -- msu start
供应商药材筛选
##        SELECT
            ms.药材表id,
            max(ms.audit) AS audit,
            max(ms.price) AS price,
            max(ms.market_price) AS market_price,
            max(ms.is_granule) AS is_granule,
            max(ms.is_decoct) AS is_decoct,
            max(ms.is_slice) AS is_slice,
            max(ms.is_cream) AS is_cream,
            max(ms.is_extract) AS is_extract,
            max(ms.is_cream_granule) AS is_cream_granule,
            max(ms.is_extract_granule) AS is_extract_granule,
            max(ms.is_drychip) AS is_drychip,
            max(ms.is_pill) AS is_pill,
            max(ms.is_powder) AS is_powder,
            max(ms.is_bolus) AS is_bolus        FROM
            供应商药材表 AS ms            INNER JOIN (
                SELECT
                    DISTINCT (ssof.供应商id) AS 供应商id                FROM
                    药库供应商关系表 AS ssof                WHERE
                    ssof.药库id IN (
                        1, 2, 8, 9, 10, 11, 12, 13, 14, 15, 17, 22,
                        24, 25, 26, 27, 31, 33
                    )
                    AND ssof.药方剂型id IN (1)
            ) tp ON tp.供应商id= ms.供应商id        WHERE
            ms.audit = 1
        GROUP BY
            ms.药材表id -- msu end ##            ) msu ON mbu.id = msu.药材表idWHERE
    msu.药材表id > 0
    AND msu.is_slice = 1order by
    total desc,
    ttid desc

相关免费学习推荐:mysql视频教程

以上是記錄 慢SQL優化實戰的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:learnku。如有侵權,請聯絡admin@php.cn刪除
SQL:掌握基礎知識的簡單步驟SQL:掌握基礎知識的簡單步驟May 02, 2025 am 12:14 AM

sqlisessential forInteractingWithRelationalDatabases,允許使用,查詢,和managedata.1)使用electToxtractData,2)插入,更新,deleteTomanagedata,3)僱用JoinsandSubqueries andsubqueries andsubqueriesforadvancedOperations,and4)避免使用commonpitfallsleclaikeLaikeLaikeLaikeLaeclaife

SQL難以學習嗎?揭穿神話SQL難以學習嗎?揭穿神話May 01, 2025 am 12:07 AM

sqlisnotinerydifficulttolearn.itbecomesmanagablewithpracticeandeseandundestandingofdatstructures.startwithbasicselectStatements,useonlineplatformsformsformsforporractice,work work workWithReaLeageWithReaTa,LearndataBaseedEndata,LearndataBaseapedSign,andEggageWithSqummunitesFortort。

MySQL和SQL:它們在數據管理中的角色MySQL和SQL:它們在數據管理中的角色Apr 30, 2025 am 12:07 AM

MySQL是數據庫系統,SQL是操作數據庫的語言。 1.MySQL存儲和管理數據,提供結構化環境。 2.SQL用於查詢、更新、刪除數據,靈活處理各種查詢需求。它們協同工作,優化性能和設計是關鍵。

SQL和MySQL:數據管理初學者指南SQL和MySQL:數據管理初學者指南Apr 29, 2025 am 12:50 AM

SQL和MySQL的區別在於,SQL是用於管理和操作關係數據庫的語言,而MySQL是實現這些操作的開源數據庫管理系統。 1)SQL允許用戶定義、操作和查詢數據,通過命令如CREATETABLE、INSERT、SELECT等實現。 2)MySQL作為RDBMS,支持這些SQL命令,並提供高性能和可靠性。 3)SQL的工作原理基於關係代數,MySQL通過查詢優化器和索引等機制優化性能。

SQL的核心功能:查詢和檢索信息SQL的核心功能:查詢和檢索信息Apr 28, 2025 am 12:11 AM

SQL查詢的核心功能是通過SELECT語句從數據庫中提取、過濾和排序信息。 1.基本用法:使用SELECT從表中查詢特定列,如SELECTname,departmentFROMemployees。 2.高級用法:結合子查詢和ORDERBY實現複雜查詢,如找出薪水高於平均值的員工並按薪水降序排列。 3.調試技巧:檢查語法錯誤,使用小規模數據驗證邏輯錯誤,利用EXPLAIN命令優化性能。 4.性能優化:使用索引,避免SELECT*,合理使用子查詢和JOIN來提高查詢效率。

SQL:數據庫的語言解釋了SQL:數據庫的語言解釋了Apr 27, 2025 am 12:14 AM

SQL是數據庫操作的核心工具,用於查詢、操作和管理數據庫。 1)SQL允許執行CRUD操作,包括數據查詢、操作、定義和控制。 2)SQL的工作原理包括解析、優化和執行三個步驟。 3)基本用法包括創建表、插入、查詢、更新和刪除數據。 4)高級用法涵蓋JOIN、子查詢和窗口函數。 5)常見錯誤包括語法、邏輯和性能問題,可通過數據庫錯誤信息、檢查查詢邏輯和使用EXPLAIN命令調試。 6)性能優化技巧包括創建索引、避免SELECT*和使用JOIN。

SQL:如何克服學習障礙SQL:如何克服學習障礙Apr 26, 2025 am 12:25 AM

要成為SQL高手,應掌握以下策略:1.了解數據庫基礎概念,如表、行、列、索引。 2.學習SQL的核心概念和工作原理,包括解析、優化和執行過程。 3.熟練使用基本和高級SQL操作,如CRUD、複雜查詢和窗口函數。 4.掌握調試技巧,使用EXPLAIN命令優化查詢性能。 5.通過實踐、利用學習資源、重視性能優化和保持好奇心來克服學習挑戰。

SQL和數據庫:完美的合作夥伴關係SQL和數據庫:完美的合作夥伴關係Apr 25, 2025 am 12:04 AM

SQL與數據庫的關係是緊密結合的,SQL是管理和操作數據庫的工具。 1.SQL是一種聲明式語言,用於數據定義、操作、查詢和控制。 2.數據庫引擎解析SQL語句並執行查詢計劃。 3.基本用法包括創建表、插入和查詢數據。 4.高級用法涉及復雜查詢和子查詢。 5.常見錯誤包括語法、邏輯和性能問題,可通過語法檢查和EXPLAIN命令調試。 6.優化技巧包括使用索引、避免全表掃描和優化查詢。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具