MySQL z dużą ilością danych

0

Witam serdecznie,
Mam taką tabelkę:

CREATE TABLE IF NOT EXISTS `kategorie` (
  `id` bigint(20) unsigned NOT NULL,
  `tytul` varchar(85) COLLATE utf8_unicode_ci DEFAULT NULL,
  `domena_url` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `enable` int(11) NOT NULL DEFAULT '0',
  `level` int(11) NOT NULL DEFAULT '0',
  `parent_id` int(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

--
-- Indeksy dla zrzutów tabel
--

--
-- Indexes for table `cms_kategorie`
--
ALTER TABLE `cms_kategorie`
  ADD PRIMARY KEY (`bf_id`),
  ADD UNIQUE KEY `bf_id` (`bf_id`),
  ADD KEY `bf_id_2` (`bf_id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT dla tabeli `cms_kategorie`
--
ALTER TABLE `cms_kategorie`
  MODIFY `bf_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT; 

Mój serwer: http://www.online.net/en/dedicated-server/dedibox-xc - z hdd sata3
Tabela ma 1.5GB.

Mój /my.cnf:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0
max_connections=600
max_user_connections=400
wait_timeout=30
interactive_timeout=50
long_query_time=5
#log-queries-not-using-indexes
#log-slow-queries=/var/log/mysql/log-slow-queries.log

#innodb_use_native_aio = 0
innodb_file_per_table

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

thread_cache_size = 256
table_cache = 1024
key_buffer = 64M
sort_buffer_size = 256K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
max_allowed_packet = 1M
tmp_table_size=64M

Niestety strony ładują się dość długo. Czy da się to jakoś przyśpieszyć?
Czy raczej to problem serwera?

0

Za mało danych podałeś. Głównie co się najczęściej wykonuje. Może SELECT, a może UPDATE+SELECT, a może.... Jeśli SELECT to z jakim warunkiem (nie sądzę, że pobierasz na raz całą tabelę)... Generalnie EXPLAIN przyjacielem twym.
No i podałeś DDL tabeli kategorie, a ALTER TABLE tabeli cms_kategorie :)

0

tak, baza nazywa się kategorie :)

W tabeli są głównie SELECTY, tak w 95%

0

a indeksy jakieś są? No i najpierw explain "długiego" zapytania

0

mam np. takie funkcje:

 $miasta = Array();
$stmt = $db->prepare("select tytul, domena_url, id FROM kategorie1   WHERE enable= 1  ORDER by RAND()  ASC limit 50;");
$stmt->execute();
    foreach ($stmt as $rowX) {
        array_push($miasta, $rowX['tytul']);
    } 
$stmt->closeCursor();
 
$produkty  = Array();
$stmt = $db->prepare("select tytul, domena_url, id FROM kategorie2   WHERE enable= 1  ORDER by RAND()  ASC limit 50;");
$stmt->execute();
    foreach ($stmt as $rowX) {
        array_push($produkty, $rowX['tytul']);
    }
$stmt->closeCursor();
 
$res = array();
foreach($miasta as $val) {
    $nazwa_miasta = baza_odczyt($val .' ' . array_shift($produkty));
    echo "<a href='".$portal_url."' title='".$nazwa_miasta."'>".$nazwa_miasta."</a>, ";
}  

tam oczywiście są jakieś inne "końcówki" tego zaytania.... np nie ma rand a jest where parent_id = ..... itp.

Jest to generalnie wyświetlanie danych z tej bazy... I to się potrafi generować ponad 60 sekund.....

0

a indeksy jakieś są? No i najpierw explain "długiego" zapytania

0

indexem jest id :)
"długie zapytania" - oznaczają że powyższy kod wykonuje się na stronie ponad 60 sekund :(

0

Problemem jest "ORDER by RAND()", niepotrzebnie sortujesz miliony elementów
Przykładowa analiza http://jan.kneschke.de/projects/mysql/order-by-rand/

0

czyli u mnie byłoby to coś takiego:

DELIMITER $$
DROP PROCEDURE IF EXISTS getRandomRecords$$
CREATE PROCEDURE getRandomRecords(IN cnt INT)
 
BEGIN
    DROP TEMPORARY TABLE IF EXISTS randomRecords;
    CREATE TEMPORARY TABLE randomRecords ( `rand_id` bigint, `tytul` VARCHAR(85),  `domena_url` VARCHAR(100) );
 
    loop_random: LOOP
        IF cnt < 1 THEN 
            LEAVE loop_random;
        END IF;
 
        INSERT INTO randomRecords
            SELECT r1.id, r1.tytul, r3.domena_url  FROM `kategorie` AS r1 JOIN
                (SELECT (RAND() *
                    (SELECT MAX(id) FROM `kategorie`)) AS id) AS r2
            WHERE r1.id >= r2.id ORDER BY r1.id ASC LIMIT 1;
        SET cnt = cnt - 1;
    END LOOP loop_random;
 
SELECT * FROM randomRecords;
END$$
DELIMITER ; 

??

Czy dobrze to pozmieniałem? Nie chciałbym uszkodzić bazy :(
Chcę w tej tmp bazie zapisać id rekordu, tytuł oraz domena_url

1 użytkowników online, w tym zalogowanych: 0, gości: 1