2013-08-16 19 views
-1

我有一個大屁股MySQL表,我需要得到滿足的條件是最近的1000行。顯而易見的方法是做PHP PDO搜索倒着MySQL中無秩序

try { 
    $stmt = $dbh->prepare("SELECT id, date, field1, field2 
    FROM big_ass_table 
    WHERE field1 >= 1000 and field2 <=4550 
    ORDER BY date DESC LIMIT 0,1000"); 
    $stmt->execute(); 
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
     print_r($row); 
    } 
    $stmt = null; 
} catch (PDOException $e) { 
    print $e->getMessage(); 
} 

但這張表已經是15M行,臨時排序按日期是永遠。將它作爲unix時間戳整數也沒有多大幫助。

我使用MongoDB的完成這個任務,建設與日期順序相反的指標試圖做的伎倆,沒有任何的排序:

$cursor=$mongodb->big_ass_table 
->find(array('$and'=>array($conditions))) 
->hint("date_-1") 
->limit(1000); 

有許多原因用mysql這個任務(保持雖然我長大的MongoDB越來越喜歡),所以我希望有一個對MySQL的方式,特別是PDO MySQL和向後搜索。

根據MySQL documentation

的index_col_name規約可以與ASC或DESC結束。這些關鍵字可用於將來的擴展,用於指定升序或降序索引值存儲。目前,他們被解析但被忽略;索引值始終以升序存儲。

所以我在這裏是死路一條。然後我訴諸PDO。是否有可能使它與類似

try { 
    $stmt = $dbh->prepare("SELECT id, date, field1, field2 
    FROM big_ass_table 
    WHERE field1 >= 1000 and field2 <=4550 
    LIMIT 0,1000", array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL)); 
    $stmt->execute(); 
    $row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST); 
    do { 
     print_r($row); 
    } while ($row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR)); 
    $stmt = null; 
} catch (PDOException $e) { 
    print $e->getMessage(); 
} 

注意我已經從最後一個刪除ORDER子句。我相信這樣,我仍然會捕獲第一1000行,然後只將它們打印倒退,與是不是我需要做的。 ¿也許,如果我刪除LIMIT子句,然後手動關閉光標,當我達到1000行將工作?或者我會超載數據庫引擎?

+0

只是在MongoDB端的一些提示 - 你不需要''和'',因爲它是默認的,你應該避免''提示()'' - 只是一個'sort({date:-1});''會做詭計。 – Derick

+0

我沒有閱讀關於mysql中索引的任何內容?什麼是你的MySQL數據定義?也許更好的指數將解決您的問題,而不會去mongo ... – Nanne

+0

@Derick我實際上比使用mongo進行排序時實現更好的提示速度,但差異可以忽略不計。 – amenadiel

回答

1

至少有2個技巧,以加快您的查詢。

  1. 添加一些使用索引的條件,但減少了要排序的行數。說,限制某些確保超出範圍的日期。
  2. 要創建反向指數 - 非常UNIX時間戳,但一個否定一個,在前面-。通過這種方式,您將獲得數據索引,但順序相反。不要忘記讓這個有符號整型的字段。
+0

我沒有我認爲我可以縮小搜索範圍,但我真的很喜歡第二個選項,我會用那個搜索!謝謝! – amenadiel

+0

像一個魅力一樣工作。另外,在一個整數字段上索引比在一個字段上索引要便宜得多時間戳 – amenadiel

2

我通常做在這種情況下:

1,SELECT MIN(id)作爲min_id FROM表WHERE條件

2,SELECT MAX(id)作爲max_id FROM表WHERE條件

3,SELECT * FROM表WHERE id> = min_id AND id < = max_id AND condition ORDER BY id DESC LIMIT 1000

這樣,你只是做您的匹配名單上的排序。當然,如果你的匹配列表很大,那麼你有一個問題。在這種情況下,看看分區表

+0

我相信這可以工作,但我會排隊3個查詢,而不是一個。不知道會發生什麼。 根據分區,我必須刪除FULLTEXT索引的文本字段,這是一個在我的搜索條件(通常我在查詢邊界幾何框中的匹配文本)。 – amenadiel