Сравнить строковую функцию в mysql по словам

#mysql #search

#mysql #Поиск

Вопрос:

Я пытаюсь создать функцию поиска в mysql. Чтобы сделать результат поиска более достоверным, мне нужно сравнить две строки по словам. Входные данные представляют собой 2 строки, а выходные данные — числовое слово, совпадающее с двумя строками. В MySQL я сделал, как показано ниже.

 CREATE DEFINER=`root`@`localhost` FUNCTION `CompareStrings`(str1 VARCHAR(255),str2 VARCHAR(255)) RETURNS double
BEGIN
DECLARE cur_position INT DEFAULT 1 ; 
DECLARE remainder TEXT;
DECLARE cur_string VARCHAR(50);
DECLARE delimiter_length TINYINT UNSIGNED;
DECLARE numberMatch INT;
DECLARE total INT;
DECLARE result DOUBLE DEFAULT 0;
DECLARE delim VARCHAR(10);
DECLARE string2 VARCHAR(255);
SET delim = ' ';

DROP TEMPORARY TABLE IF EXISTS SplitString1;
CREATE TEMPORARY TABLE SplitString1 (
    SplitString1ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT ,
    val VARCHAR(50) NOT NULL
) ENGINE=MyISAM;
DROP TEMPORARY TABLE IF EXISTS SplitString2;
CREATE TEMPORARY TABLE SplitString2 (
    SplitString1ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT ,
    val VARCHAR(50) NOT NULL
) ENGINE=MyISAM;

SET remainder = str1;
SET delimiter_length = CHAR_LENGTH(delim);

WHILE CHAR_LENGTH(remainder) > 0 AND cur_position > 0 DO
    SET cur_position = INSTR(remainder, delim);
    IF cur_position = 0 THEN
        SET cur_string = remainder;

    ELSE
        SET cur_string = LEFT(remainder, cur_position - 1);
    END IF;
    IF TRIM(cur_string) != '' THEN
        INSERT INTO SplitString1(val) VALUES (cur_string);
    END IF;
    SET remainder = SUBSTRING(remainder, cur_position   delimiter_length);
END WHILE;
SET remainder = str2;
SET cur_position = 1;
WHILE CHAR_LENGTH(remainder) > 0 AND cur_position > 0 DO
    SET cur_position = INSTR(remainder, delim);
    IF cur_position = 0 THEN
        SET cur_string = remainder;

    ELSE
        SET cur_string = LEFT(remainder, cur_position - 1);
    END IF;
    IF TRIM(cur_string) != '' THEN
        INSERT INTO SplitString2(val) VALUES (cur_string);
    END IF;
    SET remainder = SUBSTRING(remainder, cur_position   delimiter_length);
END WHILE;
SELECT count(*) INTO numberMatch 
FROM SplitString1 s1 JOIN SplitString2 s2 ON s1.val = s2.val;
RETURN result;
END
 

Идея состоит в том, чтобы создать две временные таблицы для хранения каждого слова, а затем сравнить эти 2 таблицы. Результат хороший, но производительность ужасная. У кого-нибудь есть идея получше, пожалуйста, дайте мне совет.
Большое спасибо!

Ответ №1:

Я не думаю, что это сработает так, как было заявлено.

Логика здравая, но вы не присвоили своей result переменной никакого значения. Следовательно, эта функция всегда будет возвращать 0. Заменить:

 RETURN result;
 

с

 RETURN numberMatch;
 

Также замените:

 CREATE DEFINER=`root`@`localhost` FUNCTION `CompareStrings`(str1 VARCHAR(255),str2 VARCHAR(255)) RETURNS double
 

с

 CREATE DEFINER=`root`@`localhost` FUNCTION `CompareStrings`(str1 VARCHAR(255),str2 VARCHAR(255)) RETURNS double READS SQL DATA
 

Что касается эффективности, то она выглядит довольно эффективной. Когда вы говорите «производительность ужасна» — что означает «ужасна»? Есть ли у вас какие-либо контрольные цифры, например, x звонков заняли y миллисов?

Комментарии:

1. извините за ошибку в моем сообщении, но фактически, как вы упомянули, я вернул numbermatch, и я был уверен, что эта функция работает хорошо. Проблема заключалась в том, что мне потребовалось примерно 0,015 с для сравнения двух строк в бенчмарке, а в сочетании с функцией поиска мне потребовалось около 5-6 с, всего 5 тыс. записей в базе данных. В любом случае, спасибо за ваш комментарий.