php - Ways to optimize my MySQL database -
i have mysql database contains words in standard english alphabet, using create simple scrabble word generator. database separated 26 tables: 1 each letter in alphabet. each table contains 2 columns:
- "word" column: column primary key, of type char(12), , not accept null values.
- "length" column: column contains unsigned tinyint value , not accept null values.
in application, user enters in number of letters textbox (indicating tiles) , query database using code:
// looped on 26 times, , $char letter between 'a' , 'z' // check if user entered in character $char or blank tile (signified ? in app) // check prevents me having query useless tables if (in_array($char, $lettersarray) || $blanks) { // if so, select words have length that's possible make $query = 'select word '.$char.'words length <= '.strlen($letters); $result = $db->query($query); $num_results = $result->num_rows; ($j = 0; $j < $num_results; $j++) { // determine if it's possible create word based on letters input // if so, perform appropriate code } }
everything working, application takes long time compared competition (theoretical competition, is; more of learning project created myself , doubt i'll release on internet), despite fact application on local computer. tried used automatic optimization feature of phpmyadmin, provided no noticeable speed increase.
i don't think performance problem database. structure of data store going have significant impact on performance of algorithm.
one easy-to-understand approach problem handle problem anagrams. alphabetize of letters in each of words, , store column index on it.
word dorw -------- ------- dale adel lead adel led del hello ehllo ehlp
then, given set of letters, query database matching anagrams. alphabetize set of letters passed in, , run query.
select word dictionary dorw = 'aert' rate tare tear
then, query subsets of letters:
select word dictionary dorw in ('aer','aet','art','ert')
this approach longest words returned first.
this isn't efficient approach, it's workable.
handling "blank" tile going more work, you'd need substitute possible letter it, , checking 26 possibilities done in 1 query,
if have letters abcd , blank tile, example...
select word dictionary dorw in ('aabcd','abbcd', 'abccd' , 'abcdd', 'abcde', 'abcde', 'abcdf', ..., 'abcdz')
that gets more painful when start dealing subsets...
(in crossword , jumble puzzles, there aren't blank tiles)
so may not appropriate algorithm scrabble.
there other algorithms may more efficient, @ returning shorter words first.
one approach build tree.
the root node "zero" letter word. child of root node, nodes of one-letter words. each node marked whether represented valid word or not. children of nodes, have possible three-letter words, again marked whether valid or not.
that lot of nodes. words 12 letters in length, that's total possible space of 1 + 26 + 26**2 + 26**3 + 26**4 + ...
but wouldn't need store every possible node, you'd store branches result in valid word. wouldn't have branches below ->z->z or ->x->q
however, have branch under ->x->y->l, though xyl not word, beginning of branch leading 'xylophone'
but that's tree traversal algorithm, fundamentally different.
Comments
Post a Comment