Стеллецкий В.
Мои разработки

Маленькие хитрости веб-мастера

 

 

 

 

 

 

 

 

 

 

 

 


вверх

Сортировка списка публикаций

Иногда хочется показывать список публикаций в разной сортировке. Например, по годам издания (в прямой и обратной последовательности) и внутри года по алфавиту заглавий или просто по алфавиту заглавий. Бесплатный хостинг на Народе.Ру не позволяет иметь баз данных, поэтому приходится для каждого порядка сортировки иметь отдельную страницу.

Вносить изменения на каждой странице хлопотно.

Приведенная ниже процедура (bat-файл) позволяет изменения делать только в одном файле со списком публикаций (ss.txt), и после выполнения процедуры получить готовые три веб-странички (publs.htm, publs_1.htm и publs_a.htm), которые просто остается скопировать на Веб.

Примечание: В "осле" (IE) в текстовых файлах с веб-сайта почему-то выполняются html-тэги (при локальном просмотре такого нет). Уж не взыщите, смотрите "HTML-код".

Текст процедуры sort_ss.bat:

@echo off
 rem выполнение сортировок
if exist ss13. del ss13.
sisort ss.txt ss13 /+13
if exist ss13_8-4. del ss13_8-4.
sisort ss13 ss13_8-4. /+8 /-4
if exist ss13_8-4.r del ss13_8-4.r
sisort ss13 ss13_8-4.r /+8 /-4 /r
 rem формирование веб-страниц
if exist sel0. del sel0.
if exist sel1. del sel1.
if exist sela. del sela.
copy sel.txt sel0
copy ss13_8-4.r ssi
swtmon publs.txt publs.htm
del sel0.
copy sel.txt sel1
copy ss13_8-4. ssi
swtmon publs.txt publs_1.htm
del sel1.
copy sel.txt sela
copy ss13. ssi
swtmon publs.txt publs_a.htm
del sela.

 

 

 

 

 

 

 

 

 

 

 

 

 


вверх

Использование ключевого слова IN в SQL-запросах

При переносе тезауруса с MS SQL в MySQL (для использования с microweb на cd-rom'ах) неожиданно сталкнулся с тем, что SQL-запрос, "нормально" выполняющийся на MS SQL 2000, выполняется недопустимо долго. Оказалось, что дело в использовании ключевого слова IN.

Думаю, что дело не только в версии MySQL, потому что в MS SQL у меня тоже были проблемы с временем выполнения запросов, использующих ключевое слово IN, правда, не такие катастрофические.

Итак, запрос:
SELECT count(*) as n FROM th_dict WHERE id IN (select id_dict from th_slov where word like 'Z%' and f='0' and n='1')


+----+
| n  |
+----+
| 43 |
+----+
1 row in set (1 min 59.22 sec)
после видоизменения запроса получилось:
SELECT count(*) as n FROM th_dict, (select distinct id_dict from th_slov where word like 'Z%' and f='0' and n='1') t WHERE id=id_dict

+----+
| n  |
+----+
| 43 |
+----+
1 row in set (0.67 sec)
как говорится, почувствуйте разницу.

Применялась версия MySQL, прилагаемая к microweb:
Server version: 5.0.51a-community-nt MySQL Community Edition (GPL)

Отзывы:

(13.09.2010) А вот пример на MS SQL 2000.
Задача: показать отчёт MarcSQL для текущего подмножества документов БД, отсортированный в порядке названий (поле 200a формата RUSMARC).

Решение 1:
SELECT dbo.get_ff('200','a',item),... from doc d where DOC_ID IN (список_уникальных_номеров_документов_через_запятую) order by 1;
Слишком большое время выполнения (более 30 сек.) на большом массиве документов (несколько тысяч)

Решение 2:
SELECT dbo.get_ff('200','a',item),... from doc d, (select DOC_ID from doc where DOC_ID IN (список_уникальных_номеров_документов_через_запятую)) t where d.doc_id=t.doc_id order by 1;
Время выполнения вполне приемлемое.

* get_ff - функция выделения подполя формата RUSMARC из поля ITEM MarcSQL

(21.10.2010) А вот еще пример на MS SQL 2000.
Задача: подсчитать в скольких документах тезауруса встречаются слова "английский" и "язык". Используется таблица словаря, где каждая строка соответствует встретившемуся слову. Ответ: 13456.

Решение 1:
SELECT count(*) FROM ra_dict where id in (select id_dict from (select * from ra_slov where id_dict in (select id_dict from ra_slov where word like 'английский%')) t2 where word like 'язык%') and isnull(status,'')!='D'
Время выполнения 4 мин 34 сек.

Решение 2 (избавились от конструкции in):
SELECT count(*) FROM ra_dict dict ,(select distinct id_dict from (select word,slov2.id_dict from ra_slov slov2 , (select distinct id_dict from ra_slov where word like 'английский%') nt2 where slov2.id_dict=nt2.id_dict ) t2 where word like 'язык%' ) nt1 where dict.id=nt1.id_dict and isnull(status,'')!='D'
Время выполнения меньше 1 сек.

Решение 3 (лень было перепрограммировать избавление от конструкции in на самом верхнем уровне подзапросов):
SELECT count(*) FROM ra_dict where id in (select id_dict from (select word,slov2.id_dict from ra_slov slov2,(select distinct id_dict from ra_slov where word like 'английский%') nt2 where slov2.id_dict=nt2.id_dict) t2 where word like 'язык%') and isnull(status,'')!='D'
Время выполнения тоже меньше 1 сек.

Вывод: Содержимое конструкции IN подзапроса выполняется для каждой проверяемой строки.