2017-09-20 99 views
1

我有表日誌,其中有兩個字段:action(VARCHAR 45)和info(VARCHAR 10000)。僅針對特定其他列值的一列的索引

有多種東西被記錄到這個表中,其中一個是訪問頁面時的用戶ip。對於這種情況action ='ip',info ='IP.ADD.RE.SS'。

因爲info可以記錄文本具體的事情的一些大的量,我想只能創建索引爲info場工程action =「IP」只有這樣我就可以搜索IP的快速,沒有長滿指數與「行動」。

我已經試過爲前15個字符創建INDEX,但仍然IP條目約佔所有東西的1%,對我來說似乎有點矯枉過正。 這整個解決方案已從其他人繼承,不幸的是,我現在可以做的很少,以改變整個架構

任何消化如何做到這一點正確的方式?它甚至有可能嗎?

+1

如果我聽到每次都有鎳,「我們繼承了數據模型,我們現在不能改變它......」:-( –

回答

1

有些RDBMS產品都支持你所描述的東西。它是由不同的產品稱爲partial or filtered indexes

MySQL未實施這個想法(他們沒有義務來實現它,因爲它是一個非標準的功能)。有一個要求將其作爲一項新功能:https://bugs.mysql.com/bug.php?id=76631

您可以在MySQL 5.7中模擬部分索引的一種解決方法是創建一個虛擬列,其中值爲NULL,除非action爲'ip'。然後索引虛擬列:

ALTER TABLE logs 
    ADD COLUMN ip_info VARCHAR(12) 
    AS (CASE `action` WHEN 'ip' THEN LEFT(info, 12) END), 
    ADD KEY (ip_info); 

嚴格地說,仍然索引中的每一行,但至少它不會存儲任何你的價值的,除了那裏的行動是「IP」索引。

P.S .:我沒有測試過上面的例子,所以如果有語法錯誤的話,我會道歉的。

0

無論如何,您正在過濾動作列,因此組合索引是解決方案。在列(action, info(15))上創建索引。

雖然索引中列的順序很重要。不要改變它。

+0

是的,但在這張表中也有條目如: action ='postdel',info ='用戶名:1​​23刪除帖子ID:456'以及其他許多不同信息的動作 我假設沒有其他方式,所以我不索引無動作的東西? – DevilaN

+0

但你把這個索引和一個常量進行比較,所有這些其他的條目都會被過濾掉,我真的不明白你的論點,這就是索引的用途...... – fancyPants

+0

我用測試表中的數據進行了測試。其中包含已過濾的數據和一個已滿的數據。 檢查大小的索引和... | test_acc_logs | action | 51003392 | | test_ip_logs |行動| 65536 | 65kB與51MB的索引大小無關緊要,而生產表則是100倍大。 那麼索引一切不需要的東西是否可以? – DevilaN

1

這似乎屬於「EAV」類別。你有一堆東西(ip,postdel等),每個都是可選的。其中一些需要索引,一些則不需要。

我的建議是將鍵值對放入一個JSON字符串中。併爲你想索引的任何東西製作一個專欄(在你的情況下是IP)。它可以是NULLable以儘量減少(但不能完全消除「浪費」空間

參見我blog on EAV

參見MySQL的,涉及JSON注意MariaDB的的實現:。他們需要的MySQL的較新版本或MariaDB的。

相關問題