MySQL FULLTEXT too slow?
Route heavyweight FULLTEXT reads to an in-memory search index. See the reproducible benchmarks for measured latency and throughput.
In-memory search engine with MySQL / MariaDB binlog replication
MygramDB deploys as a sidecar next to MySQL/MariaDB: the application keeps writing through the database as before, MygramDB follows the binlog to build its own in-memory search index, and only search reads are routed to MygramDB.
MySQL requires GTID mode and a replication user:
GTID and binlog
GTID is a unique identifier attached to each MySQL change; binlog is MySQL's change log. MygramDB reads the binlog and tracks how far it has read using the GTID. See the Glossary for more.
SET GLOBAL enforce_gtid_consistency = ON;
SET GLOBAL gtid_mode = OFF_PERMISSIVE;
SET GLOBAL gtid_mode = ON_PERMISSIVE;
SET GLOBAL gtid_mode = ON;
SET GLOBAL binlog_format = ROW;
SET GLOBAL binlog_row_image = FULL;
CREATE USER 'repl_user'@'%' IDENTIFIED BY 'your_password';
-- SELECT: for initial snapshot of search target tables
GRANT REPLICATION SLAVE, REPLICATION CLIENT, SELECT ON mydb.* TO 'repl_user'@'%';Persist MySQL settings
SET GLOBAL changes the running MySQL server, but the values may reset after restart. For production, also set gtid_mode=ON, binlog_format=ROW, and binlog_row_image=FULL in my.cnf or your managed MySQL parameter group.
docker run -d --name mygramdb \
-p 11016:11016 -p 8080:8080 \
-e MYSQL_HOST=your-mysql-host \
-e MYSQL_USER=repl_user \
-e MYSQL_PASSWORD=your_password \
-e MYSQL_DATABASE=mydb \
-e TABLE_NAME=articles \
-e TABLE_PRIMARY_KEY=id \
-e TABLE_TEXT_COLUMN=content \
-e TABLE_NGRAM_SIZE=2 \
-e REPLICATION_SERVER_ID=12345 \
-e NETWORK_ALLOW_CIDRS=0.0.0.0/0 \
ghcr.io/libraz/mygram-db:latestWARNING
NETWORK_ALLOW_CIDRS=0.0.0.0/0 allows connections from any IP. For production, restrict to specific ranges (e.g., 10.0.0.0/8,172.16.0.0/12).
Initial load
MygramDB does not load existing rows just by starting the process. Run SYNC articles once to build the search index from MySQL, then use SYNC STATUS to watch completion.
# Start one interactive session, then enter these commands at its prompt.
docker exec -it mygramdb mygram-cli
AUTH <API_ADMIN_TOKEN>
SYNC articles
SYNC STATUS
SEARCH articles hello worldSee Official Clients for full Node.js, Python, and Go usage.
npm install mygramdb-clientyarn add mygramdb-clientbun add mygramdb-clientimport { createMygramClient } from 'mygramdb-client'
const client = createMygramClient({ host: 'localhost', port: 11016 })
await client.connect()
const results = await client.search('app_db.articles', 'hello world', {
limit: 10
})go get github.com/libraz/go-mygram-clientimport mygram "github.com/libraz/go-mygram-client"
client := mygram.NewClient("localhost:11016")
defer client.Close()
client.Connect()
resp, _ := client.Search("app_db.articles", "hello world", mygram.SearchOptions{
Limit: 10,
})pip install mygramdb-clientfrom mygramdb_client import MygramClient, ClientConfig, SearchOptions
async with MygramClient(ClientConfig(host='localhost', port=11016)) as client:
results = await client.search(
'app_db.articles',
'hello world',
SearchOptions(limit=10),
)python-mygramdb-client on GitHub