Stary, gdzie 100000 wierszy, a gdzie 5GB? No chyba że będą tam sobie wiadomości po 500000 znaków pisać.
A jak chcesz dzielić to przez partycjonowanie, a nie rozrzucać po niewiadomo ilu tabelach.
[dodane]
Pozwoliłem sobie zrobić taki test:
Kod
DROP TABLE IF EXISTS `test`.`wiadomosci`;
CREATE TABLE `test`.`wiadomosci` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`fromID` int(10) unsigned NOT NULL,
`toID` int(10) unsigned NOT NULL,
`ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`status` enum('UNREAD','READ') NOT NULL,
`message` text NOT NULL,
PRIMARY KEY (`ID`),
KEY `index_2` (`fromID`,`toID`,`ts`,`status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO wiadomosci VALUES (null,ROUND(RAND() * 2048),ROUND(RAND() * 2048),FROM_UNIXTIME(RAND() * POW(2,32) - 1), 'UNREAD', '');
INSERT INTO wiadomosci (fromID, toID, ts, status, message) SELECT ROUND(RAND() * 2048),ROUND(RAND() * 2048),FROM_UNIXTIME(RAND() * POW(2,32) - 1), 'UNREAD', '' FROM wiadomosci; -- powtorzone kilkanascie razy, az w tabali znalazlo sie ~1 300 000 wierszy
UPDATE wiadomosci SET message = 'tutaj wstawiłem 2048 znaków'; -- uwaga, to trochę trwa :D
SHOW TABLE STATUS LIKE 'wiadomosci';
> Avg_row_length: 2343
> Data_length: 2457862144
> Index_length: 39403520
> Data_free: 3521118208
> Auto_increment: 1376221
SELECT SQL_NO_CACHE * FROM wiadomosci WHERE fromID = 1 AND toID = 585; -- najpierw sprawdzilem czy taki istnieje;)
> 1 row in set (0.00 sec)
SELECT SQL_NO_CACHE * FROM wiadomosci WHERE fromID = 1 AND ts BETWEEN 20000101 AND 20100101;
> 44 rows in set (0.01 sec)
Raczej nie tak źle?
W zależności od konkretnych zapytań trzebaby jeszcze założyć dodatkowe indeksy. Np do zapytania
Kod
SELECT SQL_NO_CACHE * FROM wiadomosci WHERE toID = 585;
przydałby się indeks zaczynający się od kolumny toID.