2016-01-21 60 views
0

我有兩個表,一個performer表和一個redirect表。 performer表有一個名爲slug的列。 redirect表具有一個名爲source的列。MySQL - 高效的正則表達式(或類似)查詢

sourceslug列都有唯一的鍵索引。

一個slug列數據的一個例子是這樣的:

this-is-a-slug 

一個source列數據的一個例子是這樣的:

this-is-a-slug.s12345 

我想要一個高效的查詢,讓我所有的redirect中的行有source列,該列以slug和「.s」字符開頭,後面跟着一個數字。

我嘗試這樣做:

select source from redirect 
join performer on 
source regexp concat('^', slug, '.s[0-9]+$'); 

這是極其緩慢。所以我決定以減少限制,並試圖此:

select source from redirect 
join performer on 
source like concat(slug, ".s%"); 

它仍然緩慢。

有沒有一種方法可以有效地做到這一點?

+0

不,這是永遠不會是有效的,直到你改變你的模式(見下面的Rick的答案)。成千上萬行是10 *小*表。 – symcbean

回答

1

放棄當前的計劃。

添加一列到redirectslug。這是對錶格的一次更改,以及更改代碼以插入它。

如果您正在運行5.7或MariaDB,請使用虛擬列,可能使用物化索引。

順便說一句,這裏是另一種方式來分割字符串:

mysql> SELECT SUBSTRING_INDEX('this-is-a-slug.s12345', '.', 1); 
+--------------------------------------------------+ 
| SUBSTRING_INDEX('this-is-a-slug.s12345', '.', 1) | 
+--------------------------------------------------+ 
| this-is-a-slug         | 
+--------------------------------------------------+ 

如果「S」是至關重要的,然後研究這些:

mysql> SELECT SUBSTRING_INDEX('this-is-a-slug.s12345', '.s', 1); 
+---------------------------------------------------+ 
| SUBSTRING_INDEX('this-is-a-slug.s12345', '.s', 1) | 
+---------------------------------------------------+ 
| this-is-a-slug         | 
+---------------------------------------------------+ 

mysql> SELECT SUBSTRING_INDEX('this-is-a-slug.invalid', '.s', 1); 
+----------------------------------------------------+ 
| SUBSTRING_INDEX('this-is-a-slug.invalid', '.s', 1) | 
+----------------------------------------------------+ 
| this-is-a-slug.invalid        | 
+----------------------------------------------------+ 
+0

感謝您的迴應。「添加一個列的源代碼有slug」。我不知道我明白這一點。「源」是一個專欄。你的意思是「重定向」?那麼情況就是這樣,那麼它會是一個簡單的連接在slug列的權利嗎?爲什麼然後我需要使用SUBSTRING_INDEX函數? – stepanian

+0

固定的'redirect'。'SUBSTRING_INDEX'是處理提取'slug'的另一種方式。 –

0

也許

join performer on left(source,length(slug)+2)=concat(slug, ".s") 

但在我看來,它是同

+0

也緩慢:(謝謝 – stepanian