背景:服務器應用程序(C#)使用下面的查詢(簡化)從數據庫中提取訂單數據。我記錄了這需要的平均時間,現在執行時間突然增加(平均從5ms到50ms)。所以我開始檢查這個查詢。使用變量時不使用索引
String ordernr = "123456789";
String sql = "SELECT * FROM MYDB.`MYTABLE` WHERE id = @id";
using (MySqlCommand cmd = new MySqlCommand(sql, conn))
{
cmd.Parameters.Add("@id", MySqlDbType.VarChar, 16).Value = ordernr;
using (MySqlDataReader reader = cmd.ExecuteReader())
{
//reading data
}
}
當我檢查在MySQL查詢時,我得到如下結果:
MariaDB [MYDB]> SET @id = '123456789';
Query OK, 0 rows affected (0.00 sec)
MariaDB [MYDB]> explain SELECT SQL_NO_CACHE * FROM MYDB.`MYTABLE` WHERE id = @id ;
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------------+
| 1 | SIMPLE | MYTABLE | ALL | NULL | NULL | NULL | NULL | 1448219 | Using where |
+------+-------------+-----------+------+---------------+------+---------+------+---------+-------------+
1 row in set (0.00 sec)
MariaDB [MYDB]> explain SELECT SQL_NO_CACHE * FROM MYDB.`MYTABLE` WHERE id = '123456789';
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
| 1 | SIMPLE | MYTABLE | const | PRIMARY | PRIMARY | 18 | const | 1 | |
+------+-------------+-----------+-------+---------------+---------+---------+-------+------+-------+
1 row in set (0.00 sec)
MariaDB [MYDB]>
現在我的問題是,爲什麼
查詢從服務器應用程序如下執行當我使用變量時,PRIMARY索引被忽略了嗎?
我不知道這是性能下降的原因(因爲在這個例子中,兩個查詢都返回0.00秒),但這讓我皺眉爲什麼會有差異。我也在服務器應用程序中使用了一個準備好的查詢和一個變量。所以我想檢查一下這是否相關。
任何人都可以解釋這一點嗎?
這是一個MySQL的問題。無論客戶端工具如何,您都會得到相同的行爲。 「ID」列的類型和索引定義是什麼?你是否傳遞一個整數ID的文本參數值? MySQL可能會將* table *數據轉換爲參數類型而不是相反,從而強制進行全表掃描 –
這確實是一個varchar字段(varchar(16)。在數據庫中,以及在C#代碼中設置的時候添加參數)。我可以補充說。 – Johan
爲什麼使用'varchar(6)'字段來存儲數字鍵?除了轉換和空間問題,排序規則是不同的,'2'在'123456'後出現。 –