【MySQL】如何對SQL語句進行跟蹤(trace)?

lhrbest發表於2017-12-27

【MySQL】如何對SQL語句進行跟蹤(trace)?





MySQL 5.6.3提供了對SQL語句的跟蹤功能,通過trace檔案可以進一步瞭解優化器是如何選擇某個執行計劃的,和Oracle10053事件類似。使用時需要先開啟設定,然後執行一次SQL,最後檢視INFORMATION_SCHEMA.OPTIMIZER_TRACE表的內容。需要注意的是,該表為臨時表,只能在當前會話進行查詢,每次查詢返回的都是最近一次執行的SQL語句。

設定時相關的引數:

mysql> show variables like '%trace%';

+------------------------------+----------------------------------------------------------------------------+

| Variable_name                | Value                                                                      |

+------------------------------+----------------------------------------------------------------------------+

| optimizer_trace              | enabled=off,one_line=off                                                   |

| optimizer_trace_features     | greedy_search=on,range_optimizer=on,dynamic_range=on,repeated_subselect=on |

| optimizer_trace_limit        | 1                                                                          |

| optimizer_trace_max_mem_size | 16384                                                                      |

| optimizer_trace_offset       | -1                                                                         |

+------------------------------+----------------------------------------------------------------------------+

5 rows in set (0.02 sec)

以下是開啟設定的命令:

SET optimizer_trace='enabled=on'; #開啟設定

SET OPTIMIZER_TRACE_MAX_MEM_SIZE=1000000;  #最大記憶體根據實際情況而定, 可以不設定

SET END_MARKERS_IN_JSON=ON;  #增加JSON格式註釋,預設為OFF

SET optimizer_trace_limit = 1; 

 






MySQL索引選擇不正確並詳細解析OPTIMIZER_TRACE格式

http://blog.csdn.net/melody_mr/article/details/48950601

一 表結構如下: 

CREATE TABLE t_audit_operate_log (
  Fid bigint(16) AUTO_INCREMENT,
  Fcreate_time int(10) unsigned NOT NULL DEFAULT '0',
  Fuser varchar(50) DEFAULT '',
  Fip bigint(16) DEFAULT NULL,
  Foperate_object_id bigint(20) DEFAULT '0',
  PRIMARY KEY (Fid),
  KEY indx_ctime (Fcreate_time),
  KEY indx_user (Fuser),
  KEY indx_objid (Foperate_object_id),
  KEY indx_ip (Fip)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

執行查詢:

MySQL> explain select count(*) from t_audit_operate_log where Fuser='XX@XX.com' and Fcreate_time>=1407081600 and Fcreate_time<=1407427199\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: t_audit_operate_log

type: ref

possible_keys: indx_ctime,indx_user

key: indx_user

key_len: 153

ref: const

rows: 2007326

Extra: Using where


發現,使用了一個不合適的索引, 不是很理想,於是改成指定索引:

mysql> explain select count(*) from t_audit_operate_log use index(indx_ctime) where Fuser='CY6016@cyou-inc.com' and Fcreate_time>=1407081600 and Fcreate_time<=1407427199\G

*************************** 1. row ***************************

id: 1

select_type: SIMPLE

table: t_audit_operate_log

type: range

possible_keys: indx_ctime

key: indx_ctime

key_len: 5

ref: NULL

rows: 670092

Extra: Using where

實際執行耗時,後者比前者快了接近10

問題: 很奇怪,優化器為何不選擇使用 indx_ctime 索引,而選擇了明顯會掃描更多行的 indx_user 索引。

分析2個索引的資料量如下:  兩個條件的唯一性對比:

select count(*) from t_audit_operate_log where Fuser='XX@XX.com';
+----------+
| count(*) |
+----------+
| 1238382 | 
+----------+

select count(*) from t_audit_operate_log where Fcreate_time>=1407254400 and Fcreate_time<=1407427199;
+----------+
| count(*) |
+----------+
| 198920 | 
+----------+

顯然,使用索引indx_ctime好於indx_user,但MySQL卻選擇了indx_user. 為什麼?

於是,使用 OPTIMIZER_TRACE進一步探索.


二  OPTIMIZER_TRACE的過程說明

以本處事例簡要說明OPTIMIZER_TRACE的過程.

檢視OPTIMIZER_TRACE方法:

1.set optimizer_trace='enabled=on';    --- 開啟trace

2.set optimizer_trace_max_mem_size=1000000;    --- 設定trace大小

3.set end_markers_in_json=on;    --- 增加trace中註釋

4.select * from information_schema.optimizer_trace\G;

[plain] view plain copy
  1. {\  
  2.   "steps": [\  
  3.     {\  
  4.       "join_preparation": {\  ---優化準備工作  
  5.         "select#": 1,\  
  6.         "steps": [\  
  7.           {\  
  8.             "expanded_query": "/* select#1 */ select count(0) AS `count(*)` from `t_audit_operate_log` where ((`t_audit_operate_log`.`Fuser` = 'XX@XX.com') and (`t_audit_operate_log`.`Fcreate_time` >= 1407081600) and (`t_audit_operate_log`.`Fcreate_time` <= 1407427199))"\  
  9.           }\  
  10.         ] /* steps */\  
  11.       } /* join_preparation */\  
  12.     },\  
  13.     {\  
  14.       "join_optimization": {\  ---優化工作的主要階段,包括邏輯優化和物理優化兩個階段  
  15.         "select#": 1,\  
  16.         "steps": [\  ---優化工作的主要階段, 邏輯優化階段  
  17.           {\  
  18.             "condition_processing": {\  ---邏輯優化,條件化簡  
  19.               "condition": "WHERE",\  
  20.               "original_condition": "((`t_audit_operate_log`.`Fuser` = 'XX@XX.com') and (`t_audit_operate_log`.`Fcreate_time` >= 1407081600) and (`t_audit_operate_log`.`Fcreate_time` <= 1407427199))",\  
  21.               "steps": [\  
  22.                 {\  
  23.                   "transformation": "equality_propagation",\  ---邏輯優化,條件化簡,等式處理  
  24.                   "resulting_condition": "((`t_audit_operate_log`.`Fuser` = 'XX@XX.com') and (`t_audit_operate_log`.`Fcreate_time` >= 1407081600) and (`t_audit_operate_log`.`Fcreate_time` <= 1407427199))"\  
  25.                 },\  
  26.                 {\  
  27.                   "transformation": "constant_propagation",\  ---邏輯優化,條件化簡,常量處理  
  28.                   "resulting_condition": "((`t_audit_operate_log`.`Fuser` = 'XX@XX.com') and (`t_audit_operate_log`.`Fcreate_time` >= 1407081600) and (`t_audit_operate_log`.`Fcreate_time` <= 1407427199))"\  
  29.                 },\  
  30.                 {\  
  31.                   "transformation": "trivial_condition_removal",\  ---邏輯優化,條件化簡,條件去除  
  32.                   "resulting_condition": "((`t_audit_operate_log`.`Fuser` = 'XX@XX.com') and (`t_audit_operate_log`.`Fcreate_time` >= 1407081600) and (`t_audit_operate_log`.`Fcreate_time` <= 1407427199))"\  
  33.                 }\  
  34.               ] /* steps */\  
  35.             } /* condition_processing */\  
  36.           },\  ---邏輯優化,條件化簡,結束  
  37.           {\  
  38.             "table_dependencies": [\  ---邏輯優化, 找出表之間的相互依賴關係. 非直接可用的優化方式.   
  39.               {\  
  40.                 "table": "`t_audit_operate_log`",\  
  41.                 "row_may_be_null": false,\  
  42.                 "map_bit": 0,\  
  43.                 "depends_on_map_bits": [\  
  44.                 ] /* depends_on_map_bits */\  
  45.               }\  
  46.             ] /* table_dependencies */\  
  47.           },\  
  48.           {\  
  49.             "ref_optimizer_key_uses": [\   ---邏輯優化,  找出備選的索引  
  50.               {\  
  51.                 "table": "`t_audit_operate_log`",\  
  52.                 "field": "Fuser",\  
  53.                 "equals": "'XX@XX.com'",\  
  54.                 "null_rejecting": false\  
  55.               }\  
  56.             ] /* ref_optimizer_key_uses */\  
  57.           },\  
  58.           {\  
  59.             "rows_estimation": [\   ---邏輯優化, 估算每個表的元組個數. 單表上進行全表掃描和索引掃描的代價估算. 每個索引都估算索引掃描代價  
  60.               {\  
  61.                 "table": "`t_audit_operate_log`",\  
  62.                 "range_analysis": {\  
  63.                   "table_scan": {\---邏輯優化, 估算每個表的元組個數. 單表上進行全表掃描的代價  
  64.                     "rows": 8150516,\  
  65.                     "cost": 1.73e6\  
  66.                   } /* table_scan */,\  
  67.                   "potential_range_indices": [\ ---邏輯優化, 列出備選的索引. 後續版本字串變為potential_range_indexes  
  68.                     {\  
  69.                       "index": "PRIMARY",\---邏輯優化, 本行表明主鍵索引不可用  
  70.                       "usable": false,\  
  71.                       "cause": "not_applicable"\  
  72.                     },\  
  73.                     {\  
  74.                       "index": "indx_ctime",\---邏輯優化, 索引indx_ctime  
  75.                       "usable": true,\  
  76.                       "key_parts": [\  
  77.                         "Fcreate_time",\  
  78.                         "Fid"\  
  79.                       ] /* key_parts */\  
  80.                     },\  
  81.                     {\  
  82.                       "index": "indx_user",\---邏輯優化, 索引indx_user  
  83.                       "usable": true,\  
  84.                       "key_parts": [\  
  85.                         "Fuser",\  
  86.                         "Fid"\  
  87.                       ] /* key_parts */\  
  88.                     },\  
  89.                     {\  
  90.                       "index": "indx_objid",\---邏輯優化, 索引  
  91.                       "usable": false,\  
  92.                       "cause": "not_applicable"\  
  93.                     },\  
  94.                     {\  
  95.                       "index": "indx_ip",\---邏輯優化, 索引  
  96.                       "usable": false,\  
  97.                       "cause": "not_applicable"\  
  98.                     }\  
  99.                   ] /* potential_range_indices */,\  
  100.                   "setup_range_conditions": [\ ---邏輯優化, 如果有可下推的條件,則帶條件考慮範圍查詢  
  101.                   ] /* setup_range_conditions */,\  
  102.                   "group_index_range": {\---邏輯優化, 如帶有GROUPBY或DISTINCT,則考慮是否有索引可優化這種操作. 並考慮帶有MIN/MAX的情況  
  103.                     "chosen": false,\  
  104.                     "cause": "not_group_by_or_distinct"\  
  105.                   } /* group_index_range */,\  
  106.                   "analyzing_range_alternatives": {\---邏輯優化,開始計算每個索引做範圍掃描的花費(等值比較是範圍掃描的特例)  
  107.                     "range_scan_alternatives": [\  
  108.                       {\  
  109.                         "index": "indx_ctime",\ ---[A]  
  110.                         "ranges": [\  
  111.                           "1407081600 <= Fcreate_time <= 1407427199"\  
  112.                         ] /* ranges */,\  
  113.                         "index_dives_for_eq_ranges": true,\  
  114.                         "rowid_ordered": false,\  
  115.                         "using_mrr": true,\  
  116.                         "index_only": false,\  
  117.                         "rows": 688362,\  
  118.                         "cost": 564553,\ ---邏輯優化,這個索引的代價最小  
  119.                         "chosen": true\ ---邏輯優化,這個索引的代價最小,被選中. (比前面的table_scan 和其他索引的代價都小)  
  120.                       },\  
  121.                       {\  
  122.                         "index": "indx_user",\  
  123.                         "ranges": [\  
  124.                           "XX@XX.com <= Fuser <= XX@XX.com"\  
  125.                         ] /* ranges */,\  
  126.                         "index_dives_for_eq_ranges": true,\  
  127.                         "rowid_ordered": true,\  
  128.                         "using_mrr": true,\  
  129.                         "index_only": false,\  
  130.                         "rows": 1945894,\  
  131.                         "cost": 1.18e6,\  
  132.                         "chosen": false,\  
  133.                         "cause": "cost"\  
  134.                       }\  
  135.                     ] /* range_scan_alternatives */,\  
  136.                     "analyzing_roworder_intersect": {\  
  137.                       "usable": false,\  
  138.                       "cause": "too_few_roworder_scans"\  
  139.                     } /* analyzing_roworder_intersect */\  
  140.                   } /* analyzing_range_alternatives */,\---邏輯優化,開始計算每個索引做範圍掃描的花費. 這項工作結算  
  141.                   "chosen_range_access_summary": {\---邏輯優化,開始計算每個索引做範圍掃描的花費. 總結本階段最優的.  
  142.                     "range_access_plan": {\  
  143.                       "type": "range_scan",\  
  144.                       "index": "indx_ctime",\  
  145.                       "rows": 688362,\  
  146.                       "ranges": [\  
  147.                         "1407081600 <= Fcreate_time <= 1407427199"\  
  148.                       ] /* ranges */\  
  149.                     } /* range_access_plan */,\  
  150.                     "rows_for_plan": 688362,\  
  151.                     "cost_for_plan": 564553,\  
  152.                     "chosen": true\    -- 這裡看到的cost和rows都比 indx_user 要來的小很多---這個和[A]處是一樣的,是資訊彙總.  
  153.                   } /* chosen_range_access_summary */\  
  154.                 } /* range_analysis */\  
  155.               }\  
  156.             ] /* rows_estimation */\ ---邏輯優化, 估算每個表的元組個數. 行估算結束  
  157.           },\  
  158.           {\  
  159.             "considered_execution_plans": [\ ---物理優化, 開始多表連線的物理優化計算  
  160.               {\  
  161.                 "plan_prefix": [\  
  162.                 ] /* plan_prefix */,\  
  163.                 "table": "`t_audit_operate_log`",\  
  164.                 "best_access_path": {\  
  165.                   "considered_access_paths": [\  
  166.                     {\  
  167.                       "access_type": "ref",\ ---物理優化, 計算indx_user索引上使用ref方查詢的花費,  
  168.                       "index": "indx_user",\  
  169.                       "rows": 1.95e6,\  
  170.                       "cost": 683515,\  
  171.                       "chosen": true\  
  172.                     },\ ---物理優化, 本應該比較所有的可用索引,即列印出多個格式相同的但索引名不同的內容,這裡卻沒有。推測是bug--沒有遍歷每一個索引.  
  173.                     {\  
  174.                       "access_type": "range",\---物理優化,猜測對應的是indx_time(沒有例項可進行除錯,對比5.7的跟蹤資訊猜測而得)  
  175.                       "rows": 516272,\  
  176.                       "cost": 702225,\---物理優化,代價大於了ref方式的683515,所以沒有被選擇  
  177.                       "chosen": false\   -- cost比上面看到的增加了很多,但rows沒什麼變化 ---物理優化,此索引沒有被選擇  
  178.                     }\  
  179.                   ] /* considered_access_paths */\  
  180.                 } /* best_access_path */,\  
  181.                 "cost_for_plan": 683515,\ ---物理優化,彙總在best_access_path 階段得到的結果  
  182.                 "rows_for_plan": 1.95e6,\  
  183.                 "chosen": true\   -- cost比上面看到的竟然小了很多?雖然rows沒啥變化  ---物理優化,彙總在best_access_path 階段得到的結果  
  184.               }\  
  185.             ] /* considered_execution_plans */\  
  186.           },\  
  187.           {\  
  188.             "attaching_conditions_to_tables": {\---邏輯優化,儘量把條件繫結到對應的表上  
  189.               } /* attaching_conditions_to_tables */\  
  190.           },\  
  191.           {\  
  192.             "refine_plan": [\  
  193.               {\  
  194.                 "table": "`t_audit_operate_log`",\---邏輯優化,下推索引條件"pushed_index_condition";其他條件附加到表上做為過濾條件"table_condition_attached"  
  195.               }\  
  196.             ] /* refine_plan */\  
  197.           }\  
  198.         ] /* steps */\  
  199.       } /* join_optimization */\ \---邏輯優化和物理優化結束  
  200.     },\  
  201.     {\  
  202.       "join_explain": {} /* join_explain */\  
  203.     }\  
  204.   ] /* steps */\  


三 其他一個相似問題
單表掃描,使用ref和range從索引獲取資料一例  
http://blog.163.com/li_hx/blog/static/183991413201461853637715/ 



四 問題的解決方式

遇到單表上有多個索引的時候,在MySQL5.6.20版本之前的版本,需要人工強制使用索引,以達到最好的效果.


注:原創地址 http://blog.csdn.net/xj626852095/article/details/52767963



我最近遇到線上一個select語句,explain選擇的索引是一樣的,這個索引是兩個欄位
比如select * from t1 where a='xxx' and b>='123123',索引是a_b(a,b)
預設情況explain顯示的索引訪問方式是ref,而force index a_b則使用了range,range訪問效果實際更好
--貼查詢執行計劃全部內容
| 1 | SIMPLE | subscribe_f8 | ref | PRIMARY,uid | uid | 8 | const | 13494670 | Using where; Using index
force index 之後
| 1 | SIMPLE | subscribe_f8 | range | uid | uid | 12 | NULL | 13494674 | Using where; Using index |
--2者計劃差別不大
就是type從ref變成range了. force 之前key_length是8,force之後是12 . 其實應該是12才是合理的
--版本支援expalin format=JSON命令嗎?支援則試試,有更詳細的代價計算值
--show create table 看看?

發來詳細的執行計劃,見 執行計劃結果一 。


	
	

執行計劃結果一

select uid_from,create_time from subscribe_f8 where  uid=12345678 and  create_time > '2013-09-08 09:54:07.0'   order by create_time asc limit 5000 | {   "steps": [     {       "join_preparation": {         "select#": 1,         "steps": [           {             "expanded_query": "/* select#1 */ select `subscribe_f8`.`uid_from` AS `uid_from`,`subscribe_f8`.`create_time` AS `create_time` from `subscribe_f8` where ((`subscribe_f8`.`uid` = 12345678) and (`subscribe_f8`.`create_time` > '2013-09-08 09:54:07.0')) order by `subscribe_f8`.`create_time` limit 5000"           }         ]       }     },     { ......           {             "considered_execution_plans": [               {                 "plan_prefix": [                 ],                 "table": "`subscribe_f8`",                 "best_access_path": {                   "considered_access_paths": [                     {                       "access_type": "ref",                       "index": "PRIMARY",                       "rows": 1.36e7,                       "cost": 3.01e6,                       "chosen": true                     },                     {                       "access_type": "ref",                       "index": "uid",                       "rows": 1.36e7,                       "cost": 2.77e6,                       "chosen": true                     },                     {                       "access_type": "range",                       "rows": 1.02e7,                       "cost": 5.46e6,                       "chosen": false                     }                   ]                 },                 "cost_for_plan": 2.77e6,                 "rows_for_plan": 1.36e7,                 "chosen": true               }             ]           }, ... }

分析: 這個問題,執行計劃指示使用ref效果更好,但實際執行時,指定使用range方式sql執行效率更高一些。
而且,通常情況下,ref的效率比range的效率要高,所以MySQL優先使用ref方式(這是一條啟發式規則)。
但究竟是否使用ref或range,MySQL還需要通過代價估算進行比較再做決定。
代價估算是一個求近似值的過程,因為計算基於的一些值是估算得來的,並不十分精準,這就造成了計算誤差。
但是,如果索引的選擇率較低(如低於10%),則使用ref的效果好於range的效果的概率大。反過來說,如果索引的選擇率較高,則ref未必range的效果好,但是因計算誤差,使得執行計劃得到了ref好於range的錯誤結論。
進一步講,如果索引的選擇率很高(如遠高於10%,這是大概值,不精確),甚至資料存放是順序連續的,有可能的是,儘管索引存在,但索引掃描的效果還差與全表掃描。
其他說明:儘管這個事例中的SQL使用了LIMIT子句,但其對ref和range方式的計算和比較,不構成影響。
進一步瞭解情況:
--這個查詢,能得到多少行元組?  佔全表的所有元組的百分比是多少?
去掉limit後,符合那個時間段的記錄數佔那個uid的88%,佔全表記錄數的的40%
進一步分析: 從更詳細的查詢執行計劃看,查詢執行計劃結果一,顯示了ref的cost是'2.77e6', 而range的cost是’5.46e6‘,這說明優化器理所當然地認為ref比range好。
可是,鑑於實際上索引選擇率太高,使得使用索引已經沒有意義(但優化器不知道這一資訊),所以實際上使用’force index (uid) ‘會得到更好的執行效果。
這就是這個想象的答案。
深入程式碼分析:best_access_path()函式中,比較了各種路徑的代價。所以是使用ref還是range甚至full table scan,在這個函式中有計算和比較。
摘錄程式碼中部分註釋如下,能表明一些含義。
 /*
    Don't test table scan if it can't be better.
    Prefer key lookup if we would use the same key for scanning.
    Don't do a table scan on InnoDB tables, if we can read the used
    parts of the row from any of the used index.
    This is because table scans uses index and we would not win
    anything by using a table scan. The only exception is INDEX_MERGE
    quick select. We can not say for sure that INDEX_MERGE quick select
    is always faster than ref access. So it's necessary to check if
    ref access is more expensive.
    We do not consider index/table scan or range access if:
    1a) The best 'ref' access produces fewer records than a table scan
        (or index scan, or range acces), and
    1b) The best 'ref' executed for all partial row combinations, is
        cheaper than a single scan. The rationale for comparing
        COST(ref_per_partial_row) * E(#partial_rows)
           vs
        COST(single_scan)
        is that if join buffering is used for the scan, then scan will
        not be performed E(#partial_rows) times, but
        E(#partial_rows)/E(#partial_rows_fit_in_buffer). At this point
        in best_access_path() we don't know this ratio, but it is
        somewhere between 1 and E(#partial_rows). To avoid
        overestimating the total cost of scanning, the heuristic used
        here has to assume that the ratio is 1. A more fine-grained
        cost comparison will be done later in this function.
    (2) This doesn't hold: the best way to perform table scan is to to perform
        'range' access using index IDX, and the best way to perform 'ref'
        access is to use the same index IDX, with the same or more key parts.
        (note: it is not clear how this rule is/should be extended to
        index_merge quick selects)
    (3) See above note about InnoDB.
    (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access
             path, but there is no quick select)
        If the condition in the above brackets holds, then the only possible
        "table scan" access method is ALL/index (there is no quick select).
        Since we have a 'ref' access path, and FORCE INDEX instructs us to
        choose it over ALL/index, there is no need to consider a full table
        scan.
  */







About Me

.............................................................................................................................................

● 本文作者:小麥苗,部分內容整理自網路,若有侵權請聯絡小麥苗刪除

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、部落格園(http://www.cnblogs.com/lhrbest)和個人微信公眾號(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文部落格園地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、個人簡介及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 資料庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA寶典今日頭條號地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

.............................................................................................................................................

● QQ群號:230161599(滿)、618766405

● 微信群:可加我微信,我拉大家進群,非誠勿擾

● 聯絡我請加QQ好友646634621,註明新增緣由

● 於 2017-12-01 09:00 ~ 2017-12-31 22:00 在魔都完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

.............................................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麥苗出版的資料庫類叢書http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客戶端掃描下面的二維碼來關注小麥苗的微信公眾號(xiaomaimiaolhr)及QQ群(DBA寶典),學習最實用的資料庫技術。

   小麥苗的微信公眾號      小麥苗的DBA寶典QQ群2     《DBA筆試面寶典》讀者群       小麥苗的微店

.............................................................................................................................................

【MySQL】如何對SQL語句進行跟蹤(trace)?
DBA筆試面試講解群
《DBA寶典》讀者群 歡迎與我聯絡



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2149385/,如需轉載,請註明出處,否則將追究法律責任。

相關文章