Форум dkLab и Denwer
Здесь общаются Web-разработчики.
Генеральный спонсор:
Хостинг «Джино»

DbSimple и кэширование. (Константин Жинько [tIT])
Author Message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Mon Dec 11, 2006 10:34 pm ()
   Post subject:
Reply with quote


М

Выделено из темы «DbSimple v2.x: лаконичная работа с различными СУБД»,
расположенной в форуме Конструктор (13 Января 2007, 15:39).
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Mon Dec 11, 2006 10:34 pm (спустя 1 секунду; написано за 18 минут 26 секунд)
   Post subject:
Reply with quote

Как обещал, рассказываю, как работать с кэшированием.

Прежде всего отмечу, что сама библиотека, разумеется, ничего не кэширует - не ее это дело. Механизм кэширования каждый придумывает себе сам. Я, например, использую memcached и результат меня просто приводит в восторг.

Пример подключения кэширования:
Code (php): скопировать код в буфер обмена
$DB = DbSimple_Generic::connect($dsn);

$DB->setCacher('my_cache_mechanism');

function my_cache_mechanism($key, $result=null, $ttl=null)
{
        //
        if ($result !== null) return set_var($key, $result, $ttl);
        else {
                //
                $result = get_var($key);
                //
                if ($result == DBSIMPLE_INVALIDATE) return false;
                //
                return $result;
        }
}
Далее смотрим примеры работы с кэшированием:
Code (php): скопировать код в буфер обмена
$DB->select('
        -- CACHE: 120
        SELECT *
        FROM test
        '

); // Закэшировать на две минуты (120 секунд)

$DB->select('
        -- CACHE: 120s
        SELECT *
        FROM test
        '

); // Закэшировать на две минуты (120 секунд)

$DB->select('
        -- CACHE: 2m
        SELECT *
        FROM test
        '

); // Закэшировать на две минуты

$DB->select('
        -- CACHE: 1h
        SELECT *
        FROM test
        '

); // Закэшировать на один час

$DB->select('
        -- CACHE: 1h 5m 15
        SELECT *
        FROM test
        '

); // Закэшировать на 1 час, 5 минут, 15 секунд

$DB->select('
        -- CACHE: test.modified
        SELECT *
        FROM test
        '

); // Закэшировать до тех пор, пока запрос SELECT MAX(test.modified) FROM test не вернет значение, отличное от момента, когда результат кэшировался

$DB->select('
        -- CACHE: 1h, test.modified
        SELECT *
        FROM test
        '

); // Закэшировать на один час и обновить кэш, если запрос SELECT MAX(test.modified) FROM test вернул значение, отличное от момента кэширования

$DB->select('
        -- CACHE: 1h, cat.modified, item.modified
        SELECT
        FROM cat, item
        WHERE cat.id=item.cat_id AND cat.id = ?
        '
,
        $cat_id
); // Закэшировать на один час и обновить кэш, если максимальное значение запроса SELECT MAX(cat.modified) FROM cat UNION SELECT MAX(item.modified) FROM item отличается...
 
Вот такая загогулина (-;
Back to top
View user's profile Send private message
Maus
Модератор



Joined: 29 Jun 2003
Posts: 8151
Карма: 271
   поощрить/наказать

Location: пос. Омсукчан Магаданской области

PostPosted: Mon Dec 11, 2006 10:38 pm (спустя 4 минуты; написано за 30 секунд)
   Post subject:
Reply with quote

Константин Жинько [tIT] wrote:
пока запрос SELECT MAX(test.modified) FROM test
почему именно MAX() ? Можно ли поставить свой валидатор?
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Tue Dec 12, 2006 1:55 am (спустя 3 часа 16 минут; написано за 10 секунд)
   Post subject:
Reply with quote

Maus wrote:
почему именно MAX()
По смыслу.
Maus wrote:
Можно ли поставить свой валидатор?
А надо ли?
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Wed Dec 13, 2006 9:32 pm (спустя 1 день 19 часов 37 минут; написано за 3 минуты 55 секунд)
   Post subject:
Reply with quote

Переделано кэширование - теперь обработчик реализуется проще:
Code (php): скопировать код в буфер обмена
$DB = DbSimple_Generic::connect($dsn);

$DB->setCacher('my_cache_mechanism');

function my_cache_mechanism($key, $result=null)
{
        //
        if ($result !== null) return set_var($key, $result);
        //
        else return get_var($key);
}
Рекомендую обновиться до версии 2.16 т.к. помимо всего прочего было исправлено несколько серьезных ошибок в модуле Ibase.
Back to top
View user's profile Send private message
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Thu Dec 14, 2006 8:20 pm (спустя 22 часа 47 минут; написано за 8 минут 46 секунд)
   Post subject:
Reply with quote

Пара вопросов.

-- CACHE: 10h 20m 30s, forum.modified, topic.modified

1) Зачем вообще нужно указывать время кеширования?
Результирующие данные из таблиц БД либо изменились, либо нет.

2) Предположим, что мне нужно использовать условные вложенные макроподстановки:
Code (SQL): скопировать код в буфер обмена
...
WHERE 1=1 {AND a > ? { AND b > ?} }
...
Получается, если я во внешний блок передам DBSIMPLE_SKIP, то внутренний удалится в любом случае?
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Thu Dec 14, 2006 10:11 pm (спустя 1 час 51 минуту; написано за 2 минуты 18 секунд)
   Post subject:
Reply with quote

Rin wrote:
Зачем вообще нужно указывать время кеширования?
Отвечаю на Ваш вопрос: затем, что не все базы данных спроектированы с возможностью получать этот самый modified - либо такого поля просто нет, либо нет доступа и т.д и т.п.
Rin wrote:
Получается, если я во внешний блок передам DBSIMPLE_SKIP, то внутренний удалится в любом случае?
А Вы проверьте (-;
Если Вам этого не надо, так и пишите без вложенных макроподстановок:
Code (SQL): скопировать код в буфер обмена
WHERE 1=1 {AND a > ?} {AND b > ?}
Back to top
View user's profile Send private message
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Wed Jan 03, 2007 6:11 pm (спустя 19 дней 19 часов 59 минут; написано за 6 минут 11 секунд)
   Post subject:
Reply with quote

А может добавить метод $db->clearCache('table_name') ?
Тоесть, если я хочу явно указать изменение определенной таблицы, дабы упростить процесс отслеживания данного явления (опционально)?
Точно так же и при запросе можно было бы ввести что-то вроде:
Code (php): скопировать код в буфер обмена
$db->query("-- UPDATE: tree
        UPDATE tree SET `field` = 'new value'"

);
Где мы явно указываем изменение таблицы tree. Мне лично не сложно лишний раз написать дополнительную строчку. Зато это значительно упрощает механизм обновления кэша.
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Tue Jan 09, 2007 10:38 am (спустя 5 дней 16 часов 27 минут; написано за 6 минут 40 секунд)
   Post subject:
Reply with quote

chin wrote:
А может добавить метод $db->clearCache('table_name') ?
Отвлекся ошибкой - забыл ответить.
chin wrote:
А может добавить метод $db->clearCache('table_name')
Это потребует более сложной структуры, хранящейся в хэше (сейчас там сырой результат для лога, готовый результат для отдачи и время последней записи), что:

1. Увеличивает размер кэша
2. Требует дорогостающих в вебе дополнительных операций по вычленению таблиц из запроса, к тому же результат будет непредсказуемым, ибо, как справедливо было замечено, чтобы распарсить SQL-запрос нужно быть SQL-сервером
chin wrote:
$db->query("-- UPDATE: tree
        UPDATE tree SET `field` = 'new value'"
);
Минут 5 думал, что Вы хотите этим сказать. Конечно заманчиво, но ресурсоемко, как и в предыдущем случае.
Иными словами, кэширование разрабатывалось для ускорения работы релиза.
Back to top
View user's profile Send private message
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Wed Jan 10, 2007 11:43 pm (спустя 1 день 13 часов 5 минут; написано за 1 минуту 55 секунд)
   Post subject:
Reply with quote

Такс, я сформировал пример реализации своей идеи с явным указанием имен таблиц, кэш которых нужно обновить (при изменении любой таблицы).
Еще раз повторю смысл самой идеи:
При выборке данных из БД (с кешированием), мы перечисляем в точности все таблицы (в скрытом атрибуте -- CACHE:), от которых зависит результат данного запроса. Тоесть, пока содержание данных таблиц будет оставаться неизменным, DbSimple может брать данные из хранилища.
Пример выборки:
Code (php): скопировать код в буфер обмена
$data = $DB->selectRow("-- CACHE: first, second
        SELECT * FROM first
        LEFT JOIN second ON second.field = first.field"

);
Тоесть, мы явно говорим DbSimple о том, что кэш результата данного запроса нужно обновить только после изменения таблиц first и second.
Теперь, как же споймать момент изменения данных в этих таблицах?
Для этого, мы точно так-же перечисляем затронутые таблицы в любых запросах добавления/обновления/удаления.
Например:
Code (php): скопировать код в буфер обмена
$DB->query("-- UPDATE: first
        INSERT INTO first SET field = 'test'"

);
Теперь DbSimple очистит кеш первого запроса, так как в нем указана зависимость от таблицы first.

Вариант реализации
Я решил использовать дополнительный файл, где будут храниться соответствия [hash запроса] => [список таблиц]. Я назвал его tables.
Для этого я использую обычные методы кеширования:
Code (php): скопировать код в буфер обмена
// Get
$tables_data = $this->_cache("tables");
// Save
$this->_cache("tables",$tables_data);
При "выборочном" запросе мы сохраняем имена таблиц в хранилище.
При "обновляющем" запросе мы ищем хеши всех запросов, где встречаются нужные нам (обновляемые) таблицы, и очищаем кеш по ним.

Для того, чтобы реализовать эту идею, я изменил Generic.php всего в двух местах... старался (:
Первое (выборка):
Code (php): скопировать код в буфер обмена
// Get the list of tables without fields specified
if (preg_match_all (www.php.net/preg_match_all)('/(?:,|^)\s*(\w+)\s*(?:,|$)/s',$cache_params,$pockets)) {
        // Get tables cache data
        if (!$tables_data = $this->_cache("tables")) {
                $tables_data = array (www.php.net/array)();
        }
        // If we don`t have this tables in cache
        if (!isset (www.php.net/isset)($tables_data[$hash])) {
                // Add and save it
                $tables_data[$hash] = $pockets[1];
                $this->_cache("tables",$tables_data);
        }
        // Remove alone tables from params .. ?
        $cache_params = trim (www.php.net/trim)(preg_replace (www.php.net/preg_replace)('/(,|^)\s*(\w+)\s*(,|$)/s','$1',$cache_params),", ");
}
Второе (обновление):
Code (php): скопировать код в буфер обмена
elseif (!empty (www.php.net/empty)($this->attributes['UPDATE']) && is_callable (www.php.net/is_callable)($this->_cacher)) do {
       
        // Get all tables from list
        if (!preg_match_all (www.php.net/preg_match_all)('/(?:,|^)\s*(\w+)\s*(?:,|$)/s',$this->attributes['UPDATE'],$pockets)) break;
       
        // Get tables cache data
        if (!$tables_data = $this->_cache("tables")) break;
       
        // Data changed flag
        $data_changed = false;
       
        // Search and remove all hashes where we have tables for update
        foreach($tables_data as $hash => $tables) {
                foreach($pockets[1] as $current) {
                        if(in_array (www.php.net/in_array)($current,$tables)) {
                                // Mark change flag
                                $data_changed = true;
                                // Clear cache
                                $this->_cache($hash,array (www.php.net/array)());
                                unset (www.php.net/unset)($tables_data[$hash]);
                                break(1);
                        }
                }
        }
       
        // Update tables cache
        if ($data_changed) {
                $this->_cache("tables",$tables_data);
        }
       
} while(0);
Кстати,
Code (php): скопировать код в буфер обмена
// Check TTL?
$ttl = empty (www.php.net/empty)($ttl) ? true : (int)$storeTime > (time (www.php.net/time)() - $ttl);
Я поменял на:
Code (php): скопировать код в буфер обмена
// Check TTL?
$ttl = empty (www.php.net/empty)($ttl) ? false : (int)$storeTime > (time (www.php.net/time)() - $ttl);
Без этого изменения у меня ничего работать не будет (изменение ни капельки не влияет на работу всего остального).

Заметьте, весь функционал DbSimple совсем не затрунут. Мы можем даже использовать вместе:
Code (php): скопировать код в буфер обмена
$data = $DB->selectRow("-- CACHE: 12h first, second, third.modified
        SELECT * FROM first
        LEFT JOIN second ON second.field = first.field"

);
(не тестировал, но должно работать)

Ах да, этот метод пригоден только в том случае, если к базе имеет доступ только наш сценарий и все запросы осуществляются через DbSimple.

У кого какое мнение?


Generic.rar
 Description:

Download
 Filename:  Generic.rar
 Filesize:  10.51 KB
 Downloaded:  944 Time(s)



Last edited by chin on Thu Jan 11, 2007 12:44 am; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Thu Jan 11, 2007 12:43 am (спустя 1 час 5 секунд; написано за 1 минуту 33 секунды)
   Post subject:
Reply with quote

chin wrote:
Code (php): скопировать код в буфер обмена
// Check TTL?
$ttl = empty (www.php.net/empty)($ttl) ? true : (int)$storeTime > (time (www.php.net/time)() - $ttl);
Я поменял на:
Code (php): скопировать код в буфер обмена
// Check TTL?
$ttl = empty (www.php.net/empty)($ttl) ? false : (int)$storeTime > (time (www.php.net/time)() - $ttl);
Без этого изменения у меня ничего работать не будет (изменение ни капельки не влияет на работу всего остального).
Пардон, вернул true на место.
Вместо этого заменил строчку
Code (php): скопировать код в буфер обмена
// Invalidate cache?
if ($ttl && $uniq_key == $invalCache) {
на
Code (php): скопировать код в буфер обмена
// Invalidate cache?
if ($ttl && $uniq_key && $uniq_key == $invalCache) {
Back to top
View user's profile Send private message Send e-mail
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Thu Jan 11, 2007 1:40 am (спустя 56 минут; написано за 3 минуты 32 секунды)
   Post subject:
Reply with quote

chin wrote:
$DB->query("-- UPDATE: first
        INSERT INTO first SET field = 'test'"
);
Кстати говоря, распарсить INSERT, UPDATE и DELETE-запросы гораздо проще, чем SELECT. Так что "-- UPDATE: first" можно и не писать, по идее - само вычислится. Правда, обновления таблиц могут происходить и в триггерах, вот это уже автоматически ну никак не отследить.

Второе: кэши не надо чистить. Достаточно для каждой таблицы хранить в отдельной записи кэша время ее последнего изменения. При сохранении кэша запроса - сохранять там также и текущее время. При фетче - проверять: если время кэша меньше, чем время изменения любой из участвующих таблиц, считать кэш недействительным. Такой алгоритм значительно быстрее работает и проще в реализации.

Но все равно, фатального недостатка метода - невозможность обновлять данные извне - это не устраняет.

Чем Вам все-таки не нравится метод с timestamp-ами, который сейчас реализован? Он вроде как более надежен...
Back to top
View user's profile Send private message Send e-mail
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Thu Jan 11, 2007 2:15 am (спустя 35 минут; написано за 12 минут 23 секунды)
   Post subject:
Reply with quote

Дмитрий Котеров wrote:
Кстати говоря, распарсить INSERT, UPDATE и DELETE-запросы гораздо проще, чем SELECT. Так что "-- UPDATE: first" можно и не писать, по идее - само вычислится.
Да, согласен. Это позволит нам забыть о том, какие таблицы где были закэшированы.
Дмитрий Котеров wrote:
Правда, обновления таблиц могут происходить и в триггерах, вот это уже автоматически ну никак не отследить.
Об этом совсем забыл... *
Дмитрий Котеров wrote:
Второе: кэши не надо чистить. Достаточно для каждой таблицы хранить в отдельной записи кэша время ее последнего изменения. При сохранении кэша запроса - сохранять там также и текущее время. При фетче - проверять: если время кэша меньше, чем время изменения любой из участвующих таблиц, считать кэш недействительным. Такой алгоритм значительно быстрее работает и проще в реализации.
Да, как-то не подумал о этом. Согласен.
Дмитрий Котеров wrote:
Но все равно, фатального недостатка метода - невозможность обновлять данные извне - это не устраняет.
* Использовать данную технологию только там, где мы уверены, что вмешательства извне не будет.
Дмитрий Котеров wrote:
Чем Вам все-таки не нравится метод с timestamp-ами, который сейчас реализован? Он вроде как более надежен...
1. Не нравится дополнительное поле timestamp + постоянно помнить о том, что нужно его добавить к данным при вставке/обновлении. Я часто использую DATETIME (удобно преобразовывать и пересчитывать в запросе), а дополнительный timestamp в такой таблице уж никуда не лезет. Лишний индекс в таблице. Мелочи.
2. Запросы SELECT MAX(modified)... хоть они и мало времени забирают, но при большом количестве подобных запросов на один прогон скрипта, становится неприятно от количества транзакция с БД. У меня на работе проект, где на за один прогон может быть загружено около 30 кэшируемых списков = 30 х SELECT MAX(modified). Вот мне и приходится искать другое решение для осуществления этой задачки. Я стараюсь стремиться к минимуму запросов в данном случае.
3. Намного проще интегрировать "-- CACHE: first" в любой уже существующий проект, не изменяя при этом структуру таблиц. Я, например, только для того, чтобы протестировать свой вариант, переделал на него полностью весь сайт, потратив на это около 20 минут.
Back to top
View user's profile Send private message Send e-mail
Kupuyc
Участник форума



Joined: 31 Mar 2006
Posts: 146
Карма: 5
   поощрить/наказать


PostPosted: Thu Jan 11, 2007 11:29 am (спустя 9 часов 13 минут; написано за 2 минуты 45 секунд)
   Post subject:
Reply with quote

Quote:
постоянно помнить о том, что нужно его добавить к данным при вставке/обновлении
Маленькое уточнение, поле timestamp, будучи не указанным в изменяющем запросе (insert, update), инициируется значением now() автоматически. Док (dev.mysql.com/doc/refman/4.1/en/timestamp-pre-4-1.html).
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Thu Jan 11, 2007 12:10 pm (спустя 40 минут; написано за 2 минуты 34 секунды)
   Post subject:
Reply with quote

chin wrote:
Не нравится дополнительное поле timestamp + постоянно помнить о том, что нужно его добавить к данным при вставке/обновлении
Стоп. Не нужно о нем помнить! Оно само обновится, на то оно и TIMESTAMP. Если в insert/update-запросе данное поле не фигурирует (либо фигурирует, но ему ставится NULL), то в поле автоматически вставляется текущий TIMESTAMP. Это работает во всех известных мне базах (правда, где-то надо через триггеры делать, но это ничего не меняет).
chin wrote:
Запросы SELECT MAX(modified)
Эти запросы во всех известных мне СУБД выполняются мгновенно при наличии индекса. Правда, с SELECT COUNT(1) в PG возникают проблемы (он тормозит, выполняя seqscan).
chin wrote:
Намного проще интегрировать "-- CACHE: first" в любой уже существующий проект, не изменяя при этом структуру таблиц.
А то, что если Вы случайно забудете где-то явно сообщить об изменении таблицы, найти эту ошибку через пару месяцев будет практически невозможно, Вы подумали?
Back to top
View user's profile Send private message Send e-mail
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Thu Jan 11, 2007 12:15 pm (спустя 5 минут; написано за 14 секунд)
   Post subject:
Reply with quote

Ок, тогда сдаюсь (:
Back to top
View user's profile Send private message Send e-mail
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Fri Jan 12, 2007 8:19 am (спустя 20 часов 3 минуты; написано за 41 секунду)
   Post subject:
Reply with quote

chin wrote:
не тестировал, но должно работать
Уже за это разработчику можно голову оторвать (-;
В остальном тут и без меня коментариев предостаточно.
Back to top
View user's profile Send private message
chin
Участник форума



Joined: 23 Feb 2005
Posts: 312
Карма: 26
   поощрить/наказать

Location: Украина, Киев

PostPosted: Fri Jan 12, 2007 11:10 am (спустя 2 часа 51 минуту; написано за 32 секунды)
   Post subject:
Reply with quote

Константин Жинько [tIT] wrote:
Уже за это разработчику можно голову оторвать (-;
Не я же не готовое решение выкладывал! А просто вариант реализации.
Back to top
View user's profile Send private message Send e-mail
Zav_guest
Guest





Карма: 388
   поощрить/наказать


PostPosted: Tue Feb 06, 2007 5:01 pm (спустя 25 дней 5 часов 51 минуту; написано за 2 минуты 8 секунд)
   Post subject:
Reply with quote

маленькое такое предложение...
1. Сделать название "childNodes" изменяем в конфиге и полем объекта не важно..
2. Вариант выборки дерева: "плоское дерево"
    т.е. все строки принадлежат одному массиву, но имеют поле "level" в зависимости от уровня вложенности
Back to top
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Wed Feb 07, 2007 11:47 am (спустя 18 часов 45 минут; написано за 2 минуты 8 секунд)
   Post subject:
Reply with quote

1. А зачем? Чем меньше настроек, тем проще пользоваться. Вряд ли кто-то будет делать в БД поле с именем "childNodes" (именно в таком регистре).
2. Древовидное дерево преобразуется в "плоское" простейшим алгоритмом. Напишите его сами и примените к результату, лично я не вижу прямой необходимости добавлять его непосредственно в библиотеку (к тому же непонятно, где в интерфейсе сообщать, получать обычное дерево или "плоское" - использовать атрибуты для этого не хотелось бы).
Back to top
View user's profile Send private message Send e-mail
DimDim
Заглянувший



Joined: 31 Jan 2007
Posts: 1
Карма: 0
   поощрить/наказать


PostPosted: Thu Feb 22, 2007 11:30 am (спустя 14 дней 23 часа 42 минуты; написано за 2 минуты 13 секунд)
   Post subject:
Reply with quote

Позвольте пару тупых вопросов по работе кеширования. У меня почему-то не удаляются закешиованные результаты ни по времени, ни после обновления указанного ключа таблицы :(

При попытке указать if ($result == DBSIMPLE_INVALIDATE) return false; ругается, что константа DBSIMPLE_INVALIDATE не определена (и я не нашел ее определения в исходниках). А если не передавать TTL в функцию кеширования, то данные живут вечно и обновляться не хотят...
Back to top
View user's profile Send private message
Дмитрий Котеров
Администратор



Joined: 10 Mar 2003
Posts: 13665
Карма: 412
   поощрить/наказать


PostPosted: Sat Feb 24, 2007 12:13 pm (спустя 2 дня 43 минуты; написано за 44 секунды)
   Post subject:
Reply with quote

DBSIMPLE_INVALIDATE и т.д. - это в старых версиях было. В новой все гораздо проще, читайте официальную документацию, а не форум.
Back to top
View user's profile Send private message Send e-mail
Guest






Карма: 388
   поощрить/наказать


PostPosted: Wed May 23, 2007 1:12 pm (спустя 2 месяца 27 дней 58 минут)
   Post subject:
Reply with quote

Подскажите, можно ли как-то реализовать примерно следуюшее?:
Code (php): скопировать код в буфер обмена
$Db->select("-- CACHE: (SELECT update FROM sites WHERE id = 1)
        < >"
);
Т.е. чтобы max() для кеша составлялся из подзапроса.
Такая конструкция не работает. Точне она выполняется, но при изменении этого самого update у 1 в таблице sites к обновлению кеша не приводит.
Спасибо.
Back to top
Константин Жинько [tIT]
Сотрудник «Лаборатории»



Joined: 12 Jun 2004
Posts: 2264
Карма: 106
   поощрить/наказать

Location: Москва

PostPosted: Wed May 23, 2007 7:08 pm (спустя 5 часов 56 минут; написано за 26 секунд)
   Post subject:
Reply with quote

Пока это не реализовано.
Back to top
View user's profile Send private message
pihel
Guest





Карма: 388
   поощрить/наказать


PostPosted: Mon Feb 18, 2008 10:23 am (спустя 8 месяцев 25 дней 15 часов 15 минут; написано за 51 секунду)
   Post subject:
Reply with quote

Поддерживаются ли префиксы в запросах с кешированием?
Запрос такого вида не хочет выполняться:
Code (SQL): скопировать код в буфер обмена
-- CACHE: ?_article.date
SELECT * FROM ?_article WHERE title_en = ?s
Back to top
Rin
Участник форума



Joined: 01 Jun 2005
Posts: 515
Карма: 185
   поощрить/наказать

Location: Москва

PostPosted: Mon Feb 18, 2008 6:49 pm (спустя 8 часов 25 минут; написано за 1 минуту 4 секунды)
   Post subject:
Reply with quote

chin
Quote:
У меня на работе проект, где на за один прогон может быть загружено около 30 кэшируемых списков = 30 х SELECT MAX(modified). Вот мне и приходится искать другое решение для осуществления этой задачки. Я стараюсь стремиться к минимуму запросов в данном случае.
Важно не кол-во запросов, а суммарное время их выполнения.
SELECT MAX(modified), как правило, работает очень быстро.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic All times are GMT + 3 Hours
Page 1 of 1    Email to a Friend.
Post a reply
Username
Subject
Господа спамеры и оптимизаторы!

Вы можете даже и не пытаться вставлять в текст поста ссылки - они все равно автоматически удаляются (вернее, тэги <a> заменяются на тэги <u>).

Но если не поверите и все же попытаетесь - как только увидите, что все безрезультатно, удалите свой пост, пожалуйста. Модераторы тоже люди, нехорошо, если они погрязнут в тоннах спама.
     

Disable BBCode in this post
Disable Smilies in this post
    HTML is OFF
BBCode is ON
Smilies are ON
You cannot post new topics in this forum. You can reply to topics in this forum. You cannot edit your posts in this forum. You cannot delete your posts in this forum. You cannot vote in polls in this forum. You cannot attach files in this forum. You can download files in this forum.
XML