회사에서 처음 알게된 Mroonga인데요. 원래 InnoDB를 쓰면 Fulltext 검색을 사용할 수 없어요. MyISAM에서 밖에 안되죠. Mroonga는 InnoDB의 특징인 트랜잭션, 외래키락 등을 지원하고 Fulltext 검색까지 원하는 엔진이에요. 

마리아디비가 10.0.15로 업데이트되면서 Mroonga가 기본적으로 포함이 되어 있어요.


1. 마리아디비 최신버전 설치

https://downloads.mariadb.org/mariadb/repositories/#mirror=kaist

리눅스계열은 소스를 받아서 컴파일하는 것보다 위처럼 레포지토리를 추가해서 하라는대로 해서 설치하는 게 빠릅니다. 위처럼 설치하면 잘 설치가 될꺼에요. 저는 우분투라 아래와 같이 설치했습니다.

sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb http://ftp.kaist.ac.kr/mariadb/repo/10.0/ubuntu trusty main'

키를 추가하고 레포지토리를 추가하면 최신버전의 mariadb를 설치할 수 있습니다.

sudo apt-get update
sudo apt-get install mariadb-server


2. Mroonga 플러그인 설치하기

원래 Mroonga도 소스받아서 컴파일하고 설치해야하는데, 최신버전인 10.0.15가 설치가 되어있다면 그냥 바로 아래 명령어로 플러그인이 설치가 됩니다.

deploy@jared-dev:/usr/bin$ mysql -uroot -p
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 38
Server version: 10.0.15-MariaDB-1~trusty mariadb.org binary distribution

Copyright (c) 2000, 2014, Oracle, SkySQL Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> INSTALL SONAME 'ha_mroonga';
Query OK, 0 rows affected (0.04 sec)

MariaDB [(none)]> show engines;
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                                    | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables                  | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                                         | NO           | NO   | NO         |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                                         | NO           | NO   | NO         |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears)             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                                      | NO           | NO   | NO         |
| MRG_MyISAM         | YES     | Collection of identical MyISAM tables                                      | NO           | NO   | NO         |
| Mroonga            | YES     | CJK-ready fulltext search, column store                                    | NO           | NO   | NO         |
| FEDERATED          | YES     | FederatedX pluggable storage engine                                        | YES          | NO   | YES        |
| InnoDB             | DEFAULT | Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | YES          | YES  | YES        |
| Aria               | YES     | Crash-safe tables with MyISAM heritage                                     | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                                     | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
11 rows in set (0.01 sec)

MariaDB [(none)]> 


3. Mroonga로 테이블 생성, InnoDB로 테이블 생성 후 비교.

Mroonga로 만드려면 아래와 같이 Engine은 Mroonga로 쓰고, fulltext key를 추가하고, fulltext key에 코멘트로 검색 옵션을 지정하면 돼요. 그리고 Engine에 코멘트를 달 수가 있는데, 이것은 InnoDB에 Wrapper Mode로 사용하겠다는 것이에요. 기본적으로 Mroonga를 생성하면 Storage Mode가 되는데, 이걸로 만들면 Transaction을 사용할 수 없어요.

CREATE TABLE `random_hangul` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `hangul` text NOT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `hangul` (`hangul`) COMMENT 'parser "TokenBigramIgnoreBlankSplitSymbolAlphaDigit"' ) ENGINE=Mroonga DEFAULT CHARSET=utf8 COMMENT='engine "InnoDB"'

아래는 그냥 InnoDB

CREATE TABLE `random_hangul2` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `hangul` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

데이터를 아래와 같이 허접한 php스크립트로 넣고-_- 넣다보니 120만개 넣었는데, 지금부터 막 느려지더라구요ㅠ 구린 컴이라ㅠ

<?php

$servername = "localhost";
$username = "root";
$password = "1234";
$db = "mudchobo";

$words = ['가', '나', '다', '라', '마', '바', '사', '아', '자', '차', '카', '타', '파', '하'];

// Create connection
$conn = mysqli_connect($servername, $username, $password, $db);

// Check connection
if (!$conn) {
    die("Connection failed: " . mysqli_connect_error());
}
echo "Connected successfully";
$conn->query("set names utf8");
for ($i = 0; $i < 1000000; $i++) {
    $randomWords = '';
    for ($j = 0; $j < 100; $j++) {
        $randomWords .= $words[mt_rand(0, count($words) - 1)];
    }
    echo 'randomWords = ' . $randomWords . PHP_EOL;

    $conn->query("insert into random_hangul(hangul) values ('$randomWords')");
}

$conn->close();


그리고 검색하면....뭐 거의 비슷한데....이상하네... 암튼 그래도 조금 더 빠르네요. 아 잘모르겠네요... 동시접속하면 더 빠르려나요 ㄷㄷ

MariaDB [mudchobo]> select count(*) from random_hangul;
+----------+
| count(*) |
+----------+
|  1298192 |
+----------+
1 row in set (0.00 sec)

MariaDB [mudchobo]> select * from random_hangul where match(hangul) against('가나다' in boolean mode);
...
45681 rows in set (1.69 sec)

MariaDB [mudchobo]> select count(*) from random_hangul2;
+----------+
| count(*) |
+----------+
|  1297523 |
+----------+
1 row in set (0.00 sec)

MariaDB [mudchobo]> select * from random_hangul2 where hangul like '%가나다%';
...
45904 rows in set (3.53 sec)

암튼 Fulltext에 옵션이 있는데, 공백과 검색, or and검색 등 다양한 옵션을 제공하니 참고요.
http://mroonga.org/docs/tutorial/wrapper.html#how-to-use-wrapper-mode

확실히 간단하게 사용할 검색이라면 쓰기에 좋을 것 같습니다.

 
Posted by 머드초보

댓글을 달아 주세요

  1. BlogIcon 타울 2018.06.07 16:10 신고  댓글주소  수정/삭제  댓글쓰기

    인덱스 검색 시간은 월등히 빠를텐데.
    읽어 오는 건수가 많아서 시간이 오래 걸린것 같습니다.

    45681 rows in set (1.69 sec)