たくさんのご意見ありがとうございます。

まず、UPをやめる+INDEX化で転送量が2/3になるのは良さそうです。
やってみます。
さらにINDEXバッファは1回だけ書けば書き換え無用ですから、純粋に2/3になりそうで良いですね。

TriangleStripで〜という方法は、いまいちわかりません。
離れた位置の四角ポリゴン(実際は三角ポリ×2)を描画する必要がある以上、TriangleStripは使えないのではないでしょうか?
縮退ポリゴン(描画されない細い三角ポリゴン)を使うことによる手法も聞いたことはありますが。

AGPメモリというのが最初よくわかりませんでしたが、D3DUSAGE_DYNAMICを指定することなんですね。
こちらも試してみます。

このほかに、下記のような手法も考えたのですが、一般的ではないのでしょうか?
説明を楽にするために、INDEXではない方法での説明とします。
・「四角形を1つ描画するのに必要な情報」を作る。つまり6頂点分。
 頂点データの中にD3DFVF_SPECULARを加え、その領域に「何個目の四角形か」を入れておく。

・上記の6頂点×描画しうる四角形分の”静的”頂点バッファを作り、情報を書き込む。
 その際D3DFVF_SPECULARの領域に入れている「何個目の四角形か」をきちんと適切な値にしておく。

・パーティクルを表現するには、四角形毎の座標情報を更新する必要がある
 そこでID3DXEffect::SetVectorArray()で座標情報を渡す

・エフェクト側ではD3DCOLORtoUBYTE4を使って、対応するVectorArrayの座標情報を引き出し、頂点座標に加算する

問題点として、ビルボードをカメラに正面向けにするためのMATRIX変換を頂点シェーダ内でやる必要があります。
(今までは、頂点データ内のxyzを正面向くように調整済みだった)