2016-09-20 9 views
0

Я пытаюсь управлять некоторыми интернет-журналами. Я в основном фиксирую, какие IP-адреса обращаются к другим IP-адресам и делают отчеты об этом.MySql - Лучшая схема для больших IP-адресов таблицы?

Проблема в том, что есть тонна болтовни, и я не уверен, смогу ли я сделать свою схему лучше.

моя схема таблицы:

CREATE TABLE `IpChatter` (
    `Id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `SourceIp` bigint(20) NULL, 
    `DestinationIp` bigint(20) NULL, 
    `SourcePort` int(11) NULL, 
    `DestinationPort` int(11) NULL, 
    `FKToSomeTableWithExtraMetaDataId` bigint(20) NOT NULL, 
    CONSTRAINT `PK_IpChatter` PRIMARY KEY (`Id` ASC) 
) ENGINE=InnoDB; 


CREATE INDEX `IX_IpChatter_FKToSomeTableWithExtraMetaDataId` ON `IpChatter` (`FKToSomeTableWithExtraMetaDataId`) using HASH; 
CREATE INDEX `IX_IpChatter_Main_Query_SourceIp` ON `IpChatter`  (`SourceIp`); 
CREATE INDEX `IX_IpChatter_Main_Query_DestinationIp` ON `IpChatter` (`DestinationIp`); 
CREATE INDEX `IX_IpChatter_Main_Query_SourcePort` ON `IpChatter`  (`SourcePort`); 
CREATE INDEX `IX_IpChatter_Main_Query_DestinationPort` ON `IpChatter` (`DestinationPort`); 


ALTER TABLE `IpChatter` ADD CONSTRAINT `FK_IpChatter_FKToSomeTableWithExtraMetaData` 
FOREIGN KEY (`FKToSomeTableWithExtraMetaDataId`) REFERENCES `FKToSomeTableWithExtraMetaData` (`Id`) 
ON DELETE CASCADE; 

Прямо сейчас у меня 2mill строк данных и отодвигается данные мне нужно примерно 4 секунды. Однако это связано с использованием данных относительно легкого тестирования. Я бы предположил, что размер данных на 30X больше в конечном продукте. Так что 4 секунды, безусловно, означают 2 миллиона в конечном продукте. Есть ли лучший способ, которым я мог бы нормализовать эти данные, или я попал в горлышко бутылки, и я не могу это сделать? Кроме того, индексы я выбрал нормально?

ответ

0

Ничего, я понял. Наверное, мне просто нужно было напечатать проблему, чтобы помочь мне придумать решение.

Итак, посмотрев мои данные, я заметил, что много пар повторяются, но под другим значением FKToSomeTableWithExtraMetaDataId.

Так говорит мне, что я могу нормализовать данные, создав таблицу с четными связями SourceIp , DestinationIp , SourcePort , DestinationPort`. Затем создайте таблицу поиска, чтобы объединить эту таблицу с таблицей ToSomeTableWithExtraMetaData.

Это уменьшает мои сырые данные IP на 1700%! Это даст огромный прирост производительности при поиске диапазона IP-адресов, и теперь он должен пройти гораздо меньше строк. Плюс с помощью таблицы поиска у меня больше гибкости в том, как я могу запросить.

CREATE TABLE `IpChatter` (
    `Id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `SourceIp` bigint(20) NULL, 
    `DestinationIp` bigint(20) NULL, 
    `SourcePort` int(11) NULL, 
    `DestinationPort` int(11) NULL, 
    `FKToSomeLookupTableId` bigint(20) NOT NULL, 
    CONSTRAINT `PK_IpChatter` PRIMARY KEY (`Id` ASC) 
) ENGINE=InnoDB; 


CREATE INDEX `IX_IpChatter_FKToSomeLookupTableId` ON `IpChatter` (`FKToSomeLookupTableId`) using HASH; 
CREATE INDEX `IX_IpChatter_Main_Query_SourceIp` ON `IpChatter`  (`SourceIp`); 
CREATE INDEX `IX_IpChatter_Main_Query_DestinationIp` ON `IpChatter` (`DestinationIp`); 
CREATE INDEX `IX_IpChatter_Main_Query_SourcePort` ON `IpChatter`  (`SourcePort`); 
CREATE INDEX `IX_IpChatter_Main_Query_DestinationPort` ON `IpChatter` (`DestinationPort`); 


ALTER TABLE `IpChatter` ADD CONSTRAINT `FK_IpChatter_FKToSomeLookupTable` 
FOREIGN KEY (`FKToSomeLookupTableId`) REFERENCES `FKToSomeLookupTable` (`Id`) 
ON DELETE CASCADE; 


CREATE TABLE `FKToSomeLookupTable` (
    `FKToSomeTableWithExtraMetaDataId` bigint(20) NOT NULL, 
    `IpChatterId` bigint(20) NOT NULL, 
    CONSTRAINT `PK_FKToSomeLookupTable` PRIMARY KEY (`Id` ASC) 
) ENGINE=InnoDB; 

CREATE INDEX `IX_IpChatter_FKToSomeTableWithExtraMetaDataId` ON `FKToSomeLookupTable` (`FKToSomeTableWithExtraMetaDataId`) using HASH; 
CREATE INDEX `IX_IpChatter_IpChatterId` ON `FKToSomeLookupTable` (`IpChatterId`) using HASH; 

ALTER TABLE `FKToSomeLookupTable` ADD CONSTRAINT `FK_FKToSomeLookupTable_FKToSomeTableWithExtraMetaData` 
FOREIGN KEY (`FKToSomeTableWithExtraMetaDataId`) REFERENCES `FKToSomeTableWithExtraMetaData` (`Id`) 
ON DELETE CASCADE; 

ALTER TABLE `FKToSomeLookupTable` ADD CONSTRAINT `FK_FKToSomeLookupTable_IpChatter` 
FOREIGN KEY (`IpChatterId`) REFERENCES `IpChatter` (`Id`) 
ON DELETE CASCADE; 
+0

Да, это называется [Rubber Duck Debugging] (https://en.wikipedia.org/wiki/Rubber_duck_debugging) – Drew

+0

hahahaha это здорово. Теперь я могу получить резиновую утку. – user2326106

0

Уменьшить размер стола. Меньший - это один из способов помочь (некоторым) со скоростью.

IPv4 может быть упакован в INT UNSIGNED, что составляет 4 байта против текущего 8-байтового BIGINT. IPv6, с другой стороны, нуждается в BINARY(16); то, что у вас есть, не будет работать.

Номер порта, я думаю, поместится в 2-байтовом SMALLINT UNSIGNED.

Ожидаете ли вы, что ваши столы будут больше 4 миллиардов рядов? Если нет, используйте INT UNSIGNED вместо BIGINT для идентификаторов.

Избавьтесь от FOREIGN KEYs, они замедляют ход вещей; Между тем, ограничения никогда не вызывали ошибку, не так ли? Вы действительно используете накладные расходы CASCADE?

Не индексируйте каждую колонку. Посмотрите на свои запросы и индексируйте столбцы или комбинации столбцов, которые выиграли бы от SELECTs, UPDATEs и DELETEs.

Просьба показать запросы; без них мы не можем судить о производительности.