2012-04-03 79 views
0

爲什麼這個MySQL查詢需要永久(並且永遠不會完成)在一個有17k行的表上?爲什麼這個簡單的查詢需要永久?

SELECT * FROM files_folders WHERE file IN (SELECT file FROM files_folders WHERE folder = 123); 

基本上,一個文件可以在幾個文件夾(物理文件及其副本)中。我試圖獲取文件夾123中的所有文件。現在在我的示例中,文件夾123中有兩個文件。ID#4222 & ID#7121。但是,這兩個文件可能在其他文件夾以及文件夾123.

我在做這個錯誤的方式還是有什麼我失蹤?

編輯:這是一個表結構的例子。

+--------------+ 
| file | folder| 
+------+-------+ 
| 1 | 1  | 
| 2 | 1  | 
| 1 | 2  | 
| 3 | 2  | 
| 4 | 3  | 
+------+-------+ 

所以我想選擇是在文件夾1中的所有文件(及複印件),這將返回:

+--------------+ 
| file | folder| 
+------+-------+ 
| 1 | 1  | 
| 2 | 1  | 
| 1 | 2  | 
+------+-------+ 

由於文件1既是文件夾1和2

謝謝。

+1

你有'文件夾'的索引嗎? – 2012-04-03 19:40:32

+0

我錯過了什麼嗎?爲什麼不只是:'SELECT * FROM files_folders WHERE Folder = 123;' – 2012-04-03 19:43:17

+0

爲什麼不只是'SELECT * FROM files_folders WHERE Folder = 123'?目前你選擇'ID',其中'Folder = 123'然後選擇'ID',其中'ID = ID'。 – David 2012-04-03 19:43:39

回答

1

使用自聯接:

SELECT 
    ff.* 
FROM 
    files_folders AS ff 
    INNER jOIN files_folders AS f ON f.ID=ff.ID 
WHERE 
    f.Folder=123 
; 
+0

這樣做。謝謝。 – ademers 2012-04-03 20:04:48

+0

我試圖做的真正的查詢是'DELETE'。 SELECT工作正常,但只要我將它合併到「DELETE」語句中,它就會永久使用。我已將查詢中的'SELECT ff。*'替換爲'DELETE ff'。任何想法爲什麼需要很長時間?謝謝。 – ademers 2012-04-03 21:08:43

+0

使用DELETE操作時,每次刪除的行都會使自連接失效,這會取消性能。對於DELETE,最好的辦法是在一個查詢中選擇文件夾ID,然後在生成的ID列表上運行DELETE查詢。這樣IN(...)的參數是不變的,導致快速刪除。 – 2012-04-03 22:07:57

2

對於每個文件,MySQL需要檢查子查詢返回的結果是否爲ID。它需要O(N)

需要完成N文件。

因此,您的查詢的複雜性爲O(N^2)。 17k^2 =〜4*10^8所以它應該需要一分鐘左右,也許更少。

爲什麼你的查詢不是

SELECT ID FROM files_folders WHERE Folder = 123 

+0

因爲一個文件也可以在另一個文件夾中。我將用表結構的示例更新我的文章。 – ademers 2012-04-03 19:49:04

-1

你爲什麼要使用子查詢?我不認爲這是必要的。你可以從表中直接選擇喜歡

SELECT * FROM files_folders WHERE Folder = 123 

和第二件事:

「因爲一個文件可以在另一個文件夾也」

這是什麼意思用子查詢?

+0

請在下次回答問題時修正語法。如果你的語法不好,很難理解你想說的話。 – ragingasiancoder 2016-07-01 13:32:02

相關問題