Structured Query Language
もうちょっとまとめよ。
DuckDB supports the dot syntax for function chaining. This allows the function call fn(arg1, arg2, arg3, ...) to be rewritten as arg1.fn(arg2, arg3, ...). For example, take the following use of the replace function:
SELECT replace(goose_name, 'goose', 'duck') AS duck_name
FROM unnest(['African goose', 'Faroese goose', 'Hungarian goose', 'Pomeranian goose']) breed(goose_name);This can be rewritten as follows:
SELECT goose_name.replace('goose', 'duck') AS duck_name
FROM unnest(['African goose', 'Faroese goose', 'Hungarian goose', 'Pomeranian goose']) breed(goose_name);
Uniform Function Call Syntaxだ!!
WITH hira_to_kata as MATERIALIZED (
SELECT hira, kata
FROM (
SELECT 'あ' as hira, 'ア' as kata
UNION SELECT 'い' as hira, 'イ' as kata
UNION SELECT 'う' as hira, 'ウ' as kata
UNION SELECT 'え' as hira, 'エ' as kata
UNION SELECT 'お' as hira, 'オ' as kata
UNION SELECT 'か' as hira, 'カ' as kata
UNION SELECT 'き' as hira, 'キ' as kata
UNION SELECT 'く' as hira, 'ク' as kata
UNION SELECT 'け' as hira, 'ケ' as kata
UNION SELECT 'こ' as hira, 'コ' as kata
UNION SELECT 'さ' as hira, 'サ' as kata
UNION SELECT 'し' as hira, 'シ' as kata
UNION SELECT 'す' as hira, 'ス' as kata
UNION SELECT 'せ' as hira, 'セ' as kata
UNION SELECT 'そ' as hira, 'ソ' as kata
UNION SELECT 'た' as hira, 'タ' as kata
UNION SELECT 'ち' as hira, 'チ' as kata
UNION SELECT 'つ' as hira, 'ツ' as kata
UNION SELECT 'て' as hira, 'テ' as kata
UNION SELECT 'と' as hira, 'ト' as kata
UNION SELECT 'な' as hira, 'ナ' as kata
UNION SELECT 'に' as hira, 'ニ' as kata
UNION SELECT 'ぬ' as hira, 'ヌ' as kata
UNION SELECT 'ね' as hira, 'ネ' as kata
UNION SELECT 'の' as hira, 'ノ' as kata
UNION SELECT 'は' as hira, 'ハ' as kata
UNION SELECT 'ひ' as hira, 'ヒ' as kata
UNION SELECT 'ふ' as hira, 'フ' as kata
UNION SELECT 'へ' as hira, 'ヘ' as kata
UNION SELECT 'ほ' as hira, 'ホ' as kata
UNION SELECT 'ま' as hira, 'マ' as kata
UNION SELECT 'み' as hira, 'ミ' as kata
UNION SELECT 'む' as hira, 'ム' as kata
UNION SELECT 'め' as hira, 'メ' as kata
UNION SELECT 'も' as hira, 'モ' as kata
UNION SELECT 'や' as hira, 'ヤ' as kata
UNION SELECT 'ゆ' as hira, 'ユ' as kata
UNION SELECT 'よ' as hira, 'ヨ' as kata
UNION SELECT 'ら' as hira, 'ラ' as kata
UNION SELECT 'り' as hira, 'リ' as kata
UNION SELECT 'る' as hira, 'ル' as kata
UNION SELECT 'れ' as hira, 'レ' as kata
UNION SELECT 'ろ' as hira, 'ロ' as kata
UNION SELECT 'わ' as hira, 'ワ' as kata
UNION SELECT 'を' as hira, 'ヲ' as kata
UNION SELECT 'ん' as hira, 'ン' as kata
UNION SELECT 'ー' as hira, 'ー' as kata
UNION SELECT 'が' as hira, 'ガ' as kata
UNION SELECT 'ぎ' as hira, 'ギ' as kata
UNION SELECT 'ぐ' as hira, 'グ' as kata
UNION SELECT 'げ' as hira, 'ゲ' as kata
UNION SELECT 'ご' as hira, 'ゴ' as kata
UNION SELECT 'ざ' as hira, 'ザ' as kata
UNION SELECT 'じ' as hira, 'ジ' as kata
UNION SELECT 'ず' as hira, 'ズ' as kata
UNION SELECT 'ぜ' as hira, 'ゼ' as kata
UNION SELECT 'ぞ' as hira, 'ゾ' as kata
UNION SELECT 'だ' as hira, 'ダ' as kata
UNION SELECT 'ぢ' as hira, 'ヂ' as kata
UNION SELECT 'づ' as hira, 'ヅ' as kata
UNION SELECT 'で' as hira, 'デ' as kata
UNION SELECT 'ど' as hira, 'ド' as kata
UNION SELECT 'ば' as hira, 'バ' as kata
UNION SELECT 'び' as hira, 'ビ' as kata
UNION SELECT 'ぶ' as hira, 'ブ' as kata
UNION SELECT 'べ' as hira, 'ベ' as kata
UNION SELECT 'ぼ' as hira, 'ボ' as kata
UNION SELECT 'ぱ' as hira, 'パ' as kata
UNION SELECT 'ぴ' as hira, 'ピ' as kata
UNION SELECT 'ぷ' as hira, 'プ' as kata
UNION SELECT 'ぺ' as hira, 'ペ' as kata
UNION SELECT 'ぽ' as hira, 'ポ' as kata
)
),
使い方はこうでござる。
いや、まあ、うん、普通にプログラム書けってかんじだ。
WITH RECURSIVE kata as (
SELECT
'' as kata,
0 as index
UNION
SELECT
CONCAT(kata.kata, hira_to_kata.kata) as kata,
kata.index + 1 as index
FROM given, kata, hira_to_kata
WHERE true
AND given.text[kata.index + 1] = hira_to_kata.hira
)
SELECT kata
FROM kata, given
WHERE true
AND kata.index = LENGTH(given.text)
「SQLにビジネスロジックを寄せる」というのを最近知って、良さそうだなと思ってたんだけど、ビジネスロジックの入力がDBから与えられるので、テストがしづらそうでもある。
そこで、「データ永続化用のDBと、ビジネスロジック用のDBを分けると良いのではないか」という考えが浮かんできた。
「ビジネスロジック用のDB」と、「データ永続化用のDB」がいい感じに連携できるのであれば、「データ永続化用のDB」にDynamoDBを使っちゃったとしても、なんか、こう、いい感じに、やれたらいいなって。
複数回発行されているSQLクエリを1回にまとめることで高速化を図った。
結果としてはDOMContentLoaded
が600ms程度から550ms程度になり、僅かに高速化された。
リンク先のコンテンツ量が乏しいリンクと前景を無効化する処理を、アクセスされた時ではなく事前に処理するようにした。
DOMContentLoaded
が550msから130msに高速化された。満足のいく結果になった。
若干サイトがもたつく気がする。度重なる機能追加で重たくなった可能性がある。実行速度の測定をしてみる。
開発環境でhtmlが渡されるまでを測定してみたところ、以下の結果となった。
開発環境:162, 145, 156, 153, 150 [ms]→平均153.2 [ms]
サーバー側のプログラムを触ってみたがそれほど高速化できなかった
Amazon Mobile Popoverの読み込み待ちで描画が遅れている。削除した。
そろそろCDNが使いたくなってきた。ただ、CDNを使うとサーバーまでアクセスが届かないので
一旦の対応としてGoogle AnalyticsをCookie無しでも動くようにした。
ローカルで動かしているときは問題ないのに、サーバで動かすとリソース(特にfavicon.svg)の取得に謎の待機時間が生じていた。600msとかの待機時間が発生していた。
nginxの設定でlimit_req_zoneが
limit_req_zone $binary_remote_addr zone=limit_req_by_ip:10m rate=1r/s;
にしてしまっていたのを、
limit_req_zone $binary_remote_addr zone=limit_req_by_ip:10m rate=10r/s;
に変更した。
秒間1アクセスまでに律速されていたのが、秒間10アクセスまで許容するようにした。
良く調べずに使うからこうなる。
調べてる途中でDBが遅いのかもしれないと思い、CREATE INDEX
した。効果はなかった。